Finalizing the bundle fails, because the ICurl instance (jota.pow.Kerl) can't absorb due to the supplied trits not having the required length.

Exception in thread "main" java.lang.RuntimeException: Illegal length: 162

at jota.pow.Kerl.absorb(Kerl.java:287)
at jota.pow.Kerl.absorb(Kerl.java:9)
at jota.model.Bundle.finalize(Bundle.java:118)

Below some example code that reproduces the error within my application.

Is there anything I should do different when creating bundles and transactions? How can I prevent this kind of error?

import jota.model.Bundle;
import jota.model.Transaction;
import jota.utils.SeedRandomGenerator;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class CreateBundle {

    public static void main(String[] args) throws IOException {
        Transaction tx = new Transaction();
        tx.setAttachmentTimestamp(System.currentTimeMillis() / 1000);
        //tx.setBundle(""); // set by finalize

        String message = "DATA_TO_BE_SAVED_ON_TANGLE".replace('_', '9');
        String messageTrytes = message + new String(new char[2187 - message.length()]).replace('\0', '9');

        Bundle bundle = new Bundle(Arrays.asList(tx), 1);

        bundle.finalize(null); // Exception in thread "main" java.lang.RuntimeException: Illegal length: 162

1 Answer 1


The Java library is quite picky about length of fields you set. In particular, the address has to be 81 trytes and both tag and obsoleteTag need to have 27 trytes. If the lengths are different (or these fields are empty), you get weird signing errors.

Changing the address to "999999999999999999999999999999999999999999999999999999999999999999999999999999999" and the two tags to "APPLICATION9TAG999999999999" makes it work for me.

I made the experience that instead of building raw Transaction objects, it is often easier to create a new Bundle, add the number of transactions needed by addEntry and then tweaking the resulting transactions (if they need tweaking for my use case) before finalizing the bundle.

  • Thanks! Now the PoW fails... Do you have some resources? I've looked at SignedCoordinator in your private-iota-testnet repository and it helped a little.
    – mike
    Commented Sep 4, 2018 at 10:02
  • 1
    When building your IOTA client, all you have to do is call .localPoW(new PearlDiverLocalPoW()) before calling .build() and PoW will be done locally by CPU. Alternatively use a node that allows remote PoW.
    – mihi
    Commented Sep 4, 2018 at 20:31
  • If I only knew sooner :D I already implemented it manually. It was a hassle till I had the trunk and branch transactions in the bundle right. Thank you!
    – mike
    Commented Sep 4, 2018 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.