{"record":{"id":"9831448bfde5b471","repo":"apache/dubbo","slug":"should-mark-before-reset","errorCode":null,"errorMessage":"should mark before reset!","messagePattern":"should mark before reset!","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/io/StreamUtils.java","lineNumber":201,"sourceCode":"             */\n            @Override\n            public synchronized void mark(int readlimit) {\n                mInMarked = true;\n                mInReset = false;\n\n                // mark buffer is not empty\n                int count = mCount - mPosition;\n                if (count > 0) {\n                    System.arraycopy(mMarkBuffer, mPosition, mMarkBuffer, 0, count);\n                    mCount = count;\n                    mPosition = 0;\n                }\n            }\n\n            @Override\n            public synchronized void reset() throws IOException {\n                if (!mInMarked) {\n                    throw new IOException(\"should mark before reset!\");\n                }\n\n                mInReset = true;\n                mPosition = 0;\n            }\n\n            @Override\n            public boolean markSupported() {\n                return true;\n            }\n\n            @Override\n            public int available() throws IOException {\n                int available = is.available();\n\n                if (mInMarked && mInReset) {\n                    available += mCount - mPosition;\n                }","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/io/StreamUtils.java#L183-L219","documentation":"Thrown by the reset() of the mark-buffering InputStream from StreamUtils.markSupportedInputStream when reset() is called before mark() has ever been called (mInMarked is false). Reset requires a marked position to rewind to; without one there is no replay point, so it raises IOException(\"should mark before reset!\"). This mirrors the contract of java.io.InputStream.reset().","triggerScenarios":"Calling reset() on a StreamUtils-marked stream without a prior mark(); calling reset() after the mark was implicitly cleared (e.g. after a full buffer cycle on some flows); reuse of a stream instance across operations where only the second calls reset().","commonSituations":"Reset-without-mark copy-paste; conditional code path that skips mark() on a fast path but still calls reset(); state machine that resets on error without ensuring mark happened.","solutions":["Always pair: call mark(readlimit) before any reset() on the same instance.","Track marked state yourself and only reset() when you have marked: if (marked) { m.reset(); marked = false; }","Prefer try-with-resources and re-open the stream rather than relying on reset for replay when mark state is uncertain."],"exampleFix":"// before\nInputStream m = StreamUtils.markSupportedInputStream(in);\nm.reset(); // -> IOException: should mark before reset!\n// after\nInputStream m = StreamUtils.markSupportedInputStream(in);\nm.mark(1024);\n// ... read ...\nm.reset();","handlingStrategy":"validation","validationCode":"boolean marked = false;\nm.mark(1024); marked = true;\n// ... read ...\nif (marked) { m.reset(); marked = false; }","typeGuard":null,"tryCatchPattern":"try {\n    m.reset();\n} catch (IOException e) {\n    // no mark set — re-open the stream instead of replaying\n    in = reopen();\n}","preventionTips":["Always pair mark() and reset() on the same instance.","Track marked state in a local and only reset() when true.","On error paths, ensure mark() actually ran before reset().","Prefer re-opening the source when mark state is uncertain."],"tags":["stream","io","mark-reset","dubbo-common"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}