apache/kafka · error · IllegalArgumentException
zstd doesn't support given compression level: level
Error message
zstd doesn't support given compression level: level
What it means
IllegalArgumentException thrown by ZstdCompression.Builder.level(int) when the requested zstd compression level is outside the supported range. Kafka pins zstd levels to the zstd library constants: minLevel=-131072 (ZSTD_minCLevel), maxLevel=22 (ZSTD_MAX_CLEVEL), defaultLevel=3. The guard is `level < -131072 || 22 < level`. Like the LZ4 check it fires at builder time, before any bytes are compressed.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/compress/ZstdCompression.java:129
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ZstdCompression that = (ZstdCompression) o;
return level == that.level;
}
@Override
public int hashCode() {
return Objects.hash(level);
}
public static class Builder implements Compression.Builder<ZstdCompression> {
private int level = ZSTD.defaultLevel();
public Builder level(int level) {
if (level < ZSTD.minLevel() || ZSTD.maxLevel() < level) {
throw new IllegalArgumentException("zstd doesn't support given compression level: " + level);
}
this.level = level;
return this;
}
@Override
public ZstdCompression build() {
return new ZstdCompression(level);
}
}
}
View on GitHub (pinned to c31c9215e1)
Solutions
- Set the zstd level to a value in [-131072, 22]; the default is 3, levels 1-19 are standard, 20-22 require --ultra and a lot of memory.
- If you do not need a specific level, omit .level() so the builder uses ZSTD.defaultLevel() (3).
- If you need extreme compression, use 19 (or 20-22 cautiously); do not exceed 22.
- Verify you are configuring the zstd codec and not accidentally applying an lz4/gzip level convention (which would under-use or over-shoot zstd's range).
Example fix
// before Compression compression = Compression.of().zstd().level(23).build(); // throws: 23 > 22 // after Compression compression = Compression.of().zstd().level(3).build(); // valid; or omit .level() to use default 3
Defensive patterns
Strategy: validation
Validate before calling
import org.apache.kafka.common.record.internal.CompressionType;
int sanitizeZstdLevel(int requested) {
int lo = CompressionType.ZSTD.minLevel();
int hi = CompressionType.ZSTD.maxLevel();
if (requested < lo || requested > hi) {
return CompressionType.ZSTD.defaultLevel();
}
return requested;
}
Compression zstd = new ZstdCompression.Builder().level(sanitizeZstdLevel(userLevel)).build(); Try / catch
try {
new ZstdCompression.Builder().level(userLevel).build();
} catch (IllegalArgumentException e) {
// message starts with "zstd doesn't support given compression level"
log.warn("Invalid zstd level {}, falling back to default", userLevel);
compression = Compression.zstd();
} Prevention
- zstd's valid range is roughly 1..22, but query ZSTD.minLevel()/maxLevel() instead of assuming.
- Higher zstd levels save bytes but cost CPU on both producer and consumer — pick deliberately.
- Keep producer and consumer kafka-clients versions aligned so the level range is identical on both sides.
When it happens
Trigger: Calling Compression.of().zstd().level(n) (or setting producer config compression.zstd.level) with n > 22 or n < -131072. The upper bound (22) is by far the more common boundary to hit; the lower bound is effectively unreachable except by accident (e.g. a sign error or treating an unsigned config as signed).
Common situations: See trigger scenarios.
Related errors
- lz4 doesn't support given compression level: level
- Compression is not yet supported with the incremental buffer
- Invalid wrapper compressionType found in legacy deep record
- The ${ProducerConfig.BUFFER_MEMORY_ALLOCATION_STRATEGY_INCRE
- Invalid producer ID and epoch values: {producerId}:{epoch}.
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/dfe11875ce69ae3c.json.
Report an issue: GitHub.