apache/kafka · error · ConfigException

Value must be between {} and {} or equal to {}

Error message

Value must be between {} and {} or equal to {}

What it means

Thrown by the GZIP level validator when the supplied level is outside [MIN_LEVEL, MAX_LEVEL] AND is not equal to DEFAULT_LEVEL. Because java.util.zip.Deflater reserves -1 (DEFAULT_COMPRESSION) as a special sentinel distinct from the 1..9 numeric range, the validator allows exactly [1..9] or -1; any other int is rejected with ConfigException.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/record/internal/CompressionType.java:60

        @Override
        public int maxLevel() {
            return MAX_LEVEL;
        }

        @Override
        public int minLevel() {
            return MIN_LEVEL;
        }

        @Override
        public ConfigDef.Validator levelValidator() {
            return ConfigDef.LambdaValidator.with((name, value) -> {
                if (value == null)
                    throw new ConfigException(name, null, "Value must be non-null");
                int level = ((Number) value).intValue();
                if (level > MAX_LEVEL || (level < MIN_LEVEL && level != DEFAULT_LEVEL)) {
                    throw new ConfigException(name, value, "Value must be between " + MIN_LEVEL + " and " + MAX_LEVEL + " or equal to " + DEFAULT_LEVEL);
                }
            }, () -> "[" + MIN_LEVEL + ",...," + MAX_LEVEL + "] or " + DEFAULT_LEVEL);
        }
    },

    // We should only load classes from a given compression library when we actually use said compression library. This
    // is because compression libraries include native code for a set of platforms and we want to avoid errors
    // in case the platform is not supported and the compression library is not actually used.
    // To ensure this, we only reference compression library code from classes that are only invoked when actual usage
    // happens.
    SNAPPY((byte) 2, "snappy", 1.0f),
    LZ4((byte) 3, "lz4", 1.0f) {
        // These values come from net.jpountz.lz4.LZ4Constants
        // We may need to update them if the lz4 library changes these values.
        private static final int MIN_LEVEL = 1;
        private static final int MAX_LEVEL = 17;
        private static final int DEFAULT_LEVEL = 9;

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Set gzip level to a value in [1..9] (higher = more CPU, smaller output) or -1 for Deflater's default.
  2. If you copied a level from a zstd/lz4 config, translate it: zstd default 3 -> gzip default -1 or 6; lz4 default 9 -> gzip 6..9.
  3. Validate the level at startup using ConfigDef.parse so the bad value fails fast instead of at runtime.

Example fix

# before
compression.type=gzip
compression.level=22

# after
compression.type=gzip
compression.level=6   # or -1 for DEFAULT_COMPRESSION
Defensive patterns

Strategy: validation

Validate before calling

// GZIP levels: must be in [MIN_LEVEL, MAX_LEVEL] or equal DEFAULT_LEVEL
int MIN = Deflater.BEST_SPEED;        // 1
int MAX = Deflater.BEST_COMPRESSION;  // 9
int DEFAULT = Deflater.DEFAULT_COMPRESSION; // -1
if (level == null) throw new ConfigException(name, null, "null");
if (!(level == DEFAULT || (level >= MIN && level <= MAX))) {
    throw new ConfigException(name, level,
        "GZIP level must be in [" + MIN + "," + MAX + "] or " + DEFAULT);
}

Type guard

// Narrow a candidate GZIP level to the valid set
static boolean isValidGzipLevel(int lvl) {
    return lvl == Deflater.DEFAULT_COMPRESSION
        || (lvl >= Deflater.BEST_SPEED && lvl <= Deflater.BEST_COMPRESSION);
}

Try / catch

try {
    type.levelValidator().ensureValid("compression.level", level);
} catch (org.apache.kafka.common.config.ConfigException e) {
    // fall back to the codec's default level
    level = type.defaultLevel();
}

Prevention

When it happens

Trigger: Setting compression.type=gzip plus a compression.level value such as 0, 10, -2, 100, etc. — anything outside [Deflater.BEST_SPEED=1, Deflater.BEST_COMPRESSION=9] and not equal to Deflater.DEFAULT_COMPRESSION (-1).

Common situations: Operators coming from zstd/lz4 where the level scale differs (zstd allows negatives down to -131072 and up to 22; lz4 uses 1..17) and reusing the same numeric level for gzip. Typographical errors (e.g., level=99).

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/71d7efe93f007a4b.json. Report an issue: GitHub.