zxing/zxing · error · IllegalArgumentException
Illegal value %s for layers
Error message
Illegal value %s for layers
What it means
Thrown by Encoder.encode when userSpecifiedLayers is non-zero and its absolute value exceeds the maximum: 4 for compact mode (negative userSpecifiedLayers) or 32 for full-size mode (positive userSpecifiedLayers). The layer count is out of the valid range. Note: negative values select compact mode, positive values select full-size mode.
Source
Thrown at core/src/main/java/com/google/zxing/aztec/encoder/Encoder.java:137
* @return Aztec symbol matrix with metadata
*/
public static AztecCode encode(byte[] data, int minECCPercent, int userSpecifiedLayers, Charset charset) {
// High-level encode
BitArray bits = new HighLevelEncoder(data, charset).encode();
// stuff bits and choose symbol size
int eccBits = bits.getSize() * minECCPercent / 100 + 11;
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)View on GitHub (pinned to 19aa2d8254)
Solutions
- Clamp userSpecifiedLayers to the valid range: [-4, -1] for compact, [1, 32] for full-size, or 0 for auto.
- Pass DEFAULT_AZTEC_LAYERS (0) to let the encoder auto-select the optimal layer count.
- Validate the layer parameter against MAX_NB_BITS (32) and MAX_NB_BITS_COMPACT (4) before calling encode.
- Remember the sign convention: negative = compact, positive = full-size.
Example fix
// before
AztecCode code = Encoder.encode(data, 33, -5, charset); // exceeds limits
// after
// Let the encoder auto-select layers (recommended)
AztecCode code = Encoder.encode(data, 33, Encoder.DEFAULT_AZTEC_LAYERS, charset);
// or validate explicitly
int layers = userSpecifiedLayers;
boolean compact = layers < 0;
int maxLayers = compact ? 4 : 32;
if (Math.abs(layers) > maxLayers) {
throw new IllegalArgumentException("Layers must be within [" + (compact ? -4 : 1) + "," + maxLayers + "]");
}
AztecCode code = Encoder.encode(data, 33, layers, charset); Defensive patterns
Strategy: validation
Validate before calling
// Validate layer count before encoding
boolean compact = userSpecifiedLayers < 0;
int maxLayers = compact ? 4 : 32;
if (userSpecifiedLayers != 0 && Math.abs(userSpecifiedLayers) > maxLayers) {
throw new IllegalArgumentException(
"Layers must be 0 (auto), [-4,-1] compact, or [1,32] full-size");
} Type guard
boolean isValidLayers(int layers) {
if (layers == 0) return true; // auto
boolean compact = layers < 0;
int max = compact ? 4 : 32;
return Math.abs(layers) <= max;
} Try / catch
try {
AztecCode code = Encoder.encode(data, minECC, userSpecifiedLayers, charset);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Illegal value")) {
// Re-run with auto-sizing
code = Encoder.encode(data, minECC, Encoder.DEFAULT_AZTEC_LAYERS, charset);
} else {
throw e;
}
} Prevention
- Use DEFAULT_AZTEC_LAYERS (0) unless you need a specific symbol size.
- Validate layer count: compact range is [-4,-1], full-size range is [1,32].
- Remember the sign convention: negative = compact, positive = full-size.
When it happens
Trigger: Encoder.encode(data, minECCPercent, userSpecifiedLayers) is called with |userSpecifiedLayers| > 4 (compact) or > 32 (full-size). For example, userSpecifiedLayers = -5 (compact mode, 5 layers > MAX_NB_BITS_COMPACT=4) or userSpecifiedLayers = 33 (full-size, 33 > MAX_NB_BITS=32).
Common situations: Passing a layer count derived from user input without clamping to the valid range. A copy-paste error using the wrong constant. Misunderstanding the sign convention (negative = compact). Passing 0 to mean '1 layer' when 0 actually means auto-size.
Related errors
- Data to large for user specified layer
- Data too large for an Aztec code
- No ECI code for character set {charset}
- ECI code must be between 0 and 999999
- Phone numbers and types lengths differ
AI-assisted analysis of zxing/zxing@19aa2d8254 (2026-08-14).
Data as JSON: /api/errors/a42221eed58684cc.
Report an issue: GitHub.