zxing/zxing · error · IllegalStateException

Failed to encode \"" + input + "\"

Error message

Failed to encode \"" + input + "\"

What it means

Thrown by MinimalEncoder.encodeHighLevel(...) when the minimum-cost path search over Data Matrix encoding modes finds no complete path (minimalJ stays -1). MinimalEncoder is a dynamic-programming encoder that, like MinimalECIInput, tries every mode combination; if no mode sequence can represent the input it gives up with this IllegalStateException. Under normal use the upstream ISO-8859-1 guard (EncoderContext) rejects unencodable input first, so this is a backstop.

Source

Thrown at core/src/main/java/com/google/zxing/datamatrix/encoder/MinimalEncoder.java:475

      }
    }

    int minimalJ = -1;
    int minimalSize = Integer.MAX_VALUE;
    for (int j = 0; j < 6; j++) {
      if (edges[inputLength][j] != null) {
        Edge edge = edges[inputLength][j];
        int size = j >= 1 && j <= 3 ? edge.cachedTotalSize + 1 : edge.cachedTotalSize; //C40, TEXT and X12 need an
                                                                                       // extra unlatch at the end
        if (size < minimalSize) {
          minimalSize = size;
          minimalJ = j;
        }
      }
    }

    if (minimalJ < 0) {
      throw new IllegalStateException("Failed to encode \"" + input + "\"");
    }
    return new Result(edges[inputLength][minimalJ]);
  }

  private static final class Edge {
    private static final int[] allCodewordCapacities = {3, 5, 8, 10, 12, 16, 18, 22, 30, 32, 36, 44, 49, 62, 86, 114,
                                                        144, 174, 204, 280, 368, 456, 576, 696, 816, 1050, 1304, 1558};
    private static final int[] squareCodewordCapacities = {3, 5, 8, 12, 18, 22, 30, 36, 44, 62, 86, 114, 144, 174, 204,
                                                           280, 368, 456, 576, 696, 816, 1050, 1304, 1558};
    private static final int[] rectangularCodewordCapacities = {5, 10, 16, 33, 32, 49};
    private final Input input;
    private final Mode mode; //the mode at the start of this edge.
    private final int fromPosition;
    private final int characterLength;
    private final Edge previous;
    private final int cachedTotalSize;

    private Edge(Input input, Mode mode, int fromPosition, int characterLength, Edge previous) {

View on GitHub (pinned to 19aa2d8254)

Solutions

  1. Route input through EncoderContext / the standard DataMatrixWriter so the Latin-1 check rejects bad input early with a clearer message.
  2. Ensure the input string is ISO-8859-1 representable before passing to MinimalEncoder.
  3. Log the exact failing input to identify the unencodable character.
Defensive patterns

Strategy: try-catch

Validate before calling

// Route through EncoderContext/DataMatrixWriter so the Latin-1 check rejects bad input early;
// confirm input is ISO-8859-1 before any direct MinimalEncoder use.

Type guard

static boolean isLatin1(String s) {
  return new String(s.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.ISO_8859_1).equals(s);
}

Try / catch

try {
  MinimalEncoder.encodeHighLevel(input);
} catch (IllegalStateException e) {
  if (e.getMessage().startsWith("Failed to encode")) {
    // surface clearer 'unsupported characters' error to caller
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing input to MinimalEncoder that no combination of Data Matrix modes can represent. In practice reached only via direct use of MinimalEncoder bypassing the normal EncoderContext charset guard.

Common situations: Custom Data Matrix pipelines that call MinimalEncoder directly with bytes/chars outside the representable range, or after manipulating internal encoding state. Rare from the public DataMatrixWriter.

Related errors


AI-assisted analysis of zxing/zxing@19aa2d8254 (2026-08-14). Data as JSON: /api/errors/3eff94c0e2249b07. Report an issue: GitHub.