zxing/zxing · error · IllegalArgumentException

Data to large for user specified layer

Error message

Data to large for user specified layer

What it means

Thrown by Encoder.encode when userSpecifiedLayers is set (non-zero) and within range, but the actual data (stuffed bits + ECC bits) exceeds the usable capacity of the chosen layer size. The user pinned a specific symbol size that is too small for the payload.

Source

Thrown at core/src/main/java/com/google/zxing/aztec/encoder/Encoder.java:145

    int totalSizeBits = bits.getSize() + eccBits;
    boolean compact;
    int layers;
    int totalBitsInLayer;
    int wordSize;
    BitArray stuffedBits;
    if (userSpecifiedLayers != DEFAULT_AZTEC_LAYERS) {
      compact = userSpecifiedLayers < 0;
      layers = Math.abs(userSpecifiedLayers);
      if (layers > (compact ? MAX_NB_BITS_COMPACT : MAX_NB_BITS)) {
        throw new IllegalArgumentException(
            String.format("Illegal value %s for layers", userSpecifiedLayers));
      }
      totalBitsInLayer = totalBitsInLayer(layers, compact);
      wordSize = WORD_SIZE[layers];
      int usableBitsInLayers = totalBitsInLayer - (totalBitsInLayer % wordSize);
      stuffedBits = stuffBits(bits, wordSize);
      if (stuffedBits.getSize() + eccBits > usableBitsInLayers) {
        throw new IllegalArgumentException("Data to large for user specified layer");
      }
      if (compact && stuffedBits.getSize() > wordSize * 64) {
        // Compact format only allows 64 data words, though C4 can hold more words than that
        throw new IllegalArgumentException("Data to large for user specified layer");
      }
    } else {
      wordSize = 0;
      stuffedBits = null;
      // We look at the possible table sizes in the order Compact1, Compact2, Compact3,
      // Compact4, Normal4,...  Normal(i) for i < 4 isn't typically used since Compact(i+1)
      // is the same size, but has more data.
      for (int i = 0; ; i++) {
        if (i > MAX_NB_BITS) {
          throw new IllegalArgumentException("Data too large for an Aztec code");
        }
        compact = i <= 3;
        layers = compact ? i + 1 : i;
        totalBitsInLayer = totalBitsInLayer(layers, compact);

View on GitHub (pinned to 19aa2d8254)

Solutions

  1. Pass userSpecifiedLayers = 0 (DEFAULT_AZTEC_LAYERS) to let the encoder auto-select the smallest sufficient layer count.
  2. If you must pin layers, increase the layer count to a larger value.
  3. Reduce minECCPercent to free up space for data bits (tradeoff: less error correction).
  4. Shorten the input data to fit the chosen symbol size.

Example fix

// before
// Pinned to 3 compact layers, but data is too large
AztecCode code = Encoder.encode(largeData, 33, -3, charset);

// after
// Auto-select layers to fit the data
AztecCode code = Encoder.encode(largeData, 33, Encoder.DEFAULT_AZTEC_LAYERS, charset);

// or increase layers
AztecCode code = Encoder.encode(largeData, 33, 5, charset); // full-size, 5 layers
Defensive patterns

Strategy: validation

Validate before calling

// Pre-estimate whether data fits in specified layers (approximate)
int dataBytes = data.length;
boolean compact = userSpecifiedLayers < 0;
int layers = Math.abs(userSpecifiedLayers);
int estBits = dataBytes * 8; // rough estimate
int eccBits = estBits * minECCPercent / 100 + 11;
int totalEst = estBits + eccBits;
// Compare against totalBitsInLayer; if close, use auto-sizing instead
// Safest: use DEFAULT_AZTEC_LAYERS (0) to auto-select.

Type guard

boolean likelyFitsLayers(byte[] data, int minECC, int layers) {
  // Heuristic: auto-sizing is always safe; manual pinning risks overflow
  return layers == 0;
}

Try / catch

try {
  AztecCode code = Encoder.encode(data, minECC, userSpecifiedLayers, charset);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("user specified layer")) {
    // Fall back to auto-sizing
    code = Encoder.encode(data, minECC, Encoder.DEFAULT_AZTEC_LAYERS, charset);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: With userSpecifiedLayers set to a valid layer count, stuffBits(bits, wordSize).getSize() + eccBits exceeds the usable bits in that layer (totalBitsInLayer minus alignment padding). The data payload is too large for the manually-selected symbol size.

Common situations: Manually specifying a small number of layers (e.g., 1 or 2) for data that needs more capacity. Increasing minECCPercent (error correction) consumes more bits, pushing the total over capacity. Not accounting for ECC overhead when choosing a layer count.

Related errors


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