{"record":{"id":"259f38502827af6b","repo":"apache/cassandra","slug":"mark-reset-not-supported","errorCode":null,"errorMessage":"Mark/Reset not supported","messagePattern":"Mark/Reset not supported","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/util/LengthAvailableInputStream.java","lineNumber":90,"sourceCode":"    {\n        return (remainingBytes <= 0) ? 0 : ((remainingBytes > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)remainingBytes);\n    }\n\n    @Override\n    public void close() throws IOException\n    {\n        in.close();\n    }\n\n    @Override\n    public synchronized void mark(int readlimit)\n    {\n    }\n\n    @Override\n    public synchronized void reset() throws IOException\n    {\n        throw new IOException(\"Mark/Reset not supported\");\n    }\n\n    @Override\n    public boolean markSupported()\n    {\n        return false;\n    }\n}\n","sourceCodeStart":72,"sourceCodeEnd":99,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/util/LengthAvailableInputStream.java#L72-L99","documentation":"LengthAvailableInputStream is a minimal wrapper that exposes a stream's length but does not support mark/reset. Calling reset() always throws IOException because markSupported() returns false and mark() is a no-op. This is standard java.io InputStream behavior for streams that cannot rewind their underlying source.","triggerScenarios":"Calling reset() on a LengthAvailableInputStream (optionally after calling mark(int)), e.g. when client code assumes all InputStreams can rewind or wraps the stream in a reader that transparently uses mark/reset such as PushbackInputStream buffering. Marking then resetting without checking markSupported() first.","commonSituations":"Code paths that re-read a header or replay bytes after discovering a different format; libraries that mark() speculatively; users copying generic InputStream-handling code that worked on ByteArrayInputStream/BufferedInputStream onto this stream.","solutions":["Check markSupported() before calling mark()/reset() and only use reset() when it returns true","Buffer the bytes you need to re-read yourself (read into a byte[] and wrap in ByteArrayInputStream, or use PushbackInputStream)","Wrap the stream in BufferedInputStream if the reset distance fits its buffer size, giving you mark/reset support","Restructure the code to re-open the underlying file/channel instead of resetting the stream"],"exampleFix":"// before\nInputStream in = new LengthAvailableInputStream(channel.newReadLength(), length);\nin.mark(1024);\nreadHeader(in);\nin.reset(); // throws IOException: Mark/Reset not supported\n// after\nInputStream in = new LengthAvailableInputStream(channel.newReadLength(), length);\nif (in.markSupported()) {\n    in.mark(1024);\n    readHeader(in);\n    in.reset();\n} else {\n    byte[] header = new byte[1024];\n    readFully(in, header);\n    InputStream headerStream = new ByteArrayInputStream(header);\n}","handlingStrategy":"validation","validationCode":"if (in.markSupported()) { in.mark(1024); ... in.reset(); } else { /* buffer manually */ }","typeGuard":"boolean canReset = in != null && in.markSupported();","tryCatchPattern":"try { in.reset(); } catch (IOException e) { /* fall back to re-open or manual buffer */ }","preventionTips":["Always check markSupported() before mark/reset","Prefer PushbackInputStream for small lookaheads","Never assume all InputStreams support reset"],"tags":["io","inputstream","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}