zxing/zxing · error · IllegalArgumentException

The number of codewords does not match the selected symbol

Error message

The number of codewords does not match the selected symbol

What it means

Thrown by ErrorCorrection.encodeECC200(String, SymbolInfo) when codewords.length() != symbolInfo.getDataCapacity(). ECC200 error correction is computed per symbol with a fixed data capacity; the input string must already be padded to exactly that length. The mismatch means the codeword stream was built against a different symbol than the one supplied.

Source

Thrown at core/src/main/java/com/google/zxing/datamatrix/encoder/ErrorCorrection.java:103

      if (p >= 256) {
        p ^= MODULO_VALUE;
      }
    }
  }

  private ErrorCorrection() {
  }

  /**
   * Creates the ECC200 error correction for an encoded message.
   *
   * @param codewords  the codewords
   * @param symbolInfo information about the symbol to be encoded
   * @return the codewords with interleaved error correction.
   */
  public static String encodeECC200(String codewords, SymbolInfo symbolInfo) {
    if (codewords.length() != symbolInfo.getDataCapacity()) {
      throw new IllegalArgumentException(
          "The number of codewords does not match the selected symbol");
    }
    StringBuilder sb = new StringBuilder(symbolInfo.getDataCapacity() + symbolInfo.getErrorCodewords());
    sb.append(codewords);
    int blockCount = symbolInfo.getInterleavedBlockCount();
    if (blockCount == 1) {
      String ecc = createECCBlock(codewords, symbolInfo.getErrorCodewords());
      sb.append(ecc);
    } else {
      sb.setLength(sb.capacity());
      int[] dataSizes = new int[blockCount];
      int[] errorSizes = new int[blockCount];
      for (int i = 0; i < blockCount; i++) {
        dataSizes[i] = symbolInfo.getDataLengthForInterleavedBlock(i + 1);
        errorSizes[i] = symbolInfo.getErrorLengthForInterleavedBlock(i + 1);
      }
      for (int block = 0; block < blockCount; block++) {
        StringBuilder temp = new StringBuilder(dataSizes[block]);

View on GitHub (pinned to 19aa2d8254)

Solutions

  1. Re-lookup SymbolInfo for the final codeword count and pad to its data capacity before calling encodeECC200.
  2. Pass the same SymbolInfo instance used to compute capacity into encodeECC200.
  3. Add an assertion codewords.length() == symbolInfo.getDataCapacity() before the call.

Example fix

// before
String ecc = ErrorCorrection.encodeECC200(codewords, someSymbol);
// after
SymbolInfo si = SymbolInfo.lookup(codewords.length()); // or the one used to build it
while (codewords.length() < si.getDataCapacity()) codewords.append((char) 129); // pad
String ecc = ErrorCorrection.encodeECC200(codewords, si);
Defensive patterns

Strategy: validation

Validate before calling

if (codewords.length() != symbolInfo.getDataCapacity()) {
  throw new IllegalArgumentException("codewords=" + codewords.length()
    + " but symbol dataCapacity=" + symbolInfo.getDataCapacity());
}
ErrorCorrection.encodeECC200(codewords, symbolInfo);

Prevention

When it happens

Trigger: Calling encodeECC200 with a codeword string whose length differs from the selected SymbolInfo's data capacity, e.g. picking a symbol after the codewords were already generated for another size, or forgetting to pad.

Common situations: Mixing symbol selection and codeword generation steps, or custom Data Matrix pipelines that change SymbolInfo between padding and ECC. The public DataMatrixWriter handles this correctly internally, so this is a custom-pipeline error.

Related errors


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