apache/kafka · warning · RuntimeException
reset not supported
Error message
reset not supported
What it means
reset() is overridden in Lz4BlockInputStream to unconditionally throw RuntimeException because the underlying ByteBuffer has already been advanced past the decompressed bytes and there is no stored mark to return to. Pairs with mark(int) (error 312) — the class declares neither operation is supported.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/compress/Lz4BlockInputStream.java:276
@Override
public int available() {
return decompressedBuffer == null ? 0 : decompressedBuffer.remaining();
}
@Override
public void close() {
bufferSupplier.release(decompressionBuffer);
}
@Override
public void mark(int readlimit) {
throw new RuntimeException("mark not supported");
}
@Override
public void reset() {
throw new RuntimeException("reset not supported");
}
/**
* Checks whether the version of lz4 on the classpath has the fix for reading from ByteBuffers with
* non-zero array offsets (see https://github.com/lz4/lz4-java/pull/65)
*/
static void detectBrokenLz4Version() {
byte[] source = new byte[]{1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3};
final LZ4Compressor compressor = LZ4Factory.fastestInstance().fastCompressor();
final byte[] compressed = new byte[compressor.maxCompressedLength(source.length)];
final int compressedLength = compressor.compress(source, 0, source.length, compressed, 0,
compressed.length);
// allocate an array-backed ByteBuffer with non-zero array-offset containing the compressed data
// a buggy decompressor will read the data from the beginning of the underlying array instead of
// the beginning of the ByteBuffer, failing to decompress the invalid data.
final byte[] zeroes = {0, 0, 0, 0, 0};View on GitHub (pinned to c31c9215e1)
Solutions
- Eliminate the reset() call; Lz4BlockInputStream is single-pass.
- Buffer the decompressed output into a byte[] or ByteBuffer upstream and replay from there.
- Verify the calling library honors markSupported()==false before invoking reset().
Example fix
// before
InputStream in = new Lz4BlockInputStream(buf, supplier, true);
in.mark(0);
readHeader(in);
in.reset();
// after
ByteArrayOutputStream tmp = new ByteArrayOutputStream();
try (InputStream in = new Lz4BlockInputStream(buf, supplier, true)) {
in.transferTo(tmp);
}
byte[] all = tmp.toByteArray(); // replay as many times as needed Defensive patterns
Strategy: validation
Validate before calling
// Symmetric to mark(): reset() is only valid when markSupported() is true.
InputStream in = ...;
if (in.markSupported()) {
in.reset();
} else {
throw new IllegalStateException("Cannot reset non-bufferable LZ4 stream; re-open the source");
} Type guard
static boolean canReset(InputStream in) {
return in != null && in.markSupported(); // reset capability == mark capability in java.io
} Try / catch
try {
in.reset();
} catch (RuntimeException e) {
if ("reset not supported".equals(e.getMessage())) {
// re-open the LZ4 stream from the original ByteBuffer instead of resetting.
} else throw e;
} Prevention
- Treat decompressed Kafka records as a forward-only cursor; do not design parsing that requires rewinding.
- If replay is required, materialize the decompressed output once into a byte[] or list and iterate that repeatedly.
- Pair every mark() with a guarded reset() — static analysis tools can flag unguarded reset() calls.
- Document at the call site that the stream is consumed exactly once.
When it happens
Trigger: Any invocation of Lz4BlockInputStream.reset(), e.g. from a parser or wrapper that previously called mark() and now attempts to rewind. Reached at line 276. Often thrown right after error 312 if a caller ignores the mark() failure.
Common situations: Same shape as error 312: third-party IO/serialization libraries that assume mark/reset; migrating code from a resettable stream; defensive reset() calls in cleanup paths. Indicates the caller violated the documented InputStream contract for this class.
Related errors
- mark not supported
- The stream is already closed
- Stream ended prematurely
- Stream unsupported (invalid magic bytes)
- Stream frame descriptor corrupted
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/0d2cf3831618f1df.json.
Report an issue: GitHub.