{"record":{"id":"d73a2e8f0b55376e","repo":"apache/dubbo","slug":"mark-buffer-is-full","errorCode":null,"errorMessage":"Mark buffer is full!","messagePattern":"Mark buffer is full!","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/io/StreamUtils.java","lineNumber":155,"sourceCode":"            public int read() throws IOException {\n                if (!mInMarked) {\n                    return is.read();\n                } else {\n                    if (mPosition < mCount) {\n                        byte b = mMarkBuffer[mPosition++];\n                        return b & 0xFF;\n                    }\n\n                    if (!mInReset) {\n                        if (mDry) {\n                            return -1;\n                        }\n\n                        if (null == mMarkBuffer) {\n                            mMarkBuffer = new byte[markBufferSize];\n                        }\n                        if (mPosition >= markBufferSize) {\n                            throw new IOException(\"Mark buffer is full!\");\n                        }\n\n                        int read = is.read();\n                        if (-1 == read) {\n                            mDry = true;\n                            return -1;\n                        }\n\n                        mMarkBuffer[mPosition++] = (byte) read;\n                        mCount++;\n\n                        return read;\n                    } else {\n                        // mark buffer is used, exit mark status!\n                        mInMarked = false;\n                        mInReset = false;\n                        mPosition = 0;\n                        mCount = 0;","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/io/StreamUtils.java#L137-L173","documentation":"Thrown by the mark-buffering InputStream created in StreamUtils.markSupportedInputStream(InputStream, int markBufferSize) when, after mark() has been set, the number of bytes read exceeds markBufferSize. This wrapper is used only when the underlying stream does not support mark/reset itself; it buffers bytes between mark() and reset() in a fixed-size array, and once mPosition reaches markBufferSize it raises IOException(\"Mark buffer is full!\"). It is the direct analogue of java.io's 'Read ahead limit exceeded' but with an explicit, user-controlled cap.","triggerScenarios":"Wrapping a non-markable stream with markSupportedInputStream(in, N), calling mark(N), then reading more than N bytes before reset(); or calling the single-arg markSupportedInputStream(in) whose default buffer is too small for the replay window.","commonSituations":"Replaying HTTP response bodies, multipart parsing, or protocol peeking where the consumed-ahead bytes exceed the configured buffer; default buffer size used for a stream that needs a large lookahead; mark(readlimit) ignored — this implementation ignores readlimit and uses the constructor cap.","solutions":["Size markBufferSize to the maximum bytes you will read between mark() and reset(), e.g. markSupportedInputStream(in, requiredLookahead).","Call reset() as early as possible once the decision point is passed, to free the buffer.","Avoid wrapping already-markable streams (the wrapper returns the original unchanged when markSupported() is true)."],"exampleFix":"// before\nInputStream m = StreamUtils.markSupportedInputStream(in); // default cap too small\nm.mark(64);\n// ... read 4KB to inspect ...\nm.reset(); // -> IOException: Mark buffer is full!\n// after\nInputStream m = StreamUtils.markSupportedInputStream(in, 8 * 1024); // cap >= lookahead\nm.mark(64);\n// ... read up to 8KB ...\nm.reset();","handlingStrategy":"validation","validationCode":"int requiredLookahead = 8 * 1024; // >= max bytes between mark() and reset()\nInputStream m = StreamUtils.markSupportedInputStream(in, requiredLookahead);\nm.mark(requiredLookahead);","typeGuard":"static int markBufferSizeFor(int maxReadAhead) {\n    return Math.max(maxReadAhead, 1);\n}","tryCatchPattern":"try {\n    m.reset();\n} catch (IOException e) {\n    // buffer too small — re-open the source and re-read instead of replaying\n    in = reopen(); m = StreamUtils.markSupportedInputStream(in, biggerCap);\n}","preventionTips":["Choose markBufferSize >= the maximum bytes you will read before reset().","Note mark(readlimit) is ignored — only the constructor cap matters.","Call reset() as soon as the decision point passes to free the buffer.","Don't wrap streams that already support mark — the wrapper returns them unchanged."],"tags":["stream","io","mark-reset","buffer","dubbo-common"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}