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(
at jota.pow.Kerl.absorb(
at jota.model.Bundle.finalize(

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.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
up vote 1 down vote accepted

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 Sep 4 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 Sep 4 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 Sep 4 at 20:41

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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