{"record":{"id":"eb961ff0d747a69a","repo":"alibaba/Sentinel","slug":"buf-index-out-of-range-bg-buf-length-len","errorCode":null,"errorMessage":"buf index out of range: {bg}, buf.length={len}","messagePattern":"buf index out of range: (.+?), buf\\.length=(.+?)","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/client/SimpleHttpResponseParser.java","lineNumber":70,"sourceCode":"\n    /**\n     * Parse bytes from an input stream to a {@link SimpleHttpResponse}.\n     *\n     * @param in input stream\n     * @return parsed HTTP response entity\n     * @throws IOException when an IO error occurs\n     */\n    public SimpleHttpResponse parse(InputStream in) throws IOException {\n        int bg = 0;\n        int len;\n        String statusLine = null;\n        Map<String, String> headers = new HashMap<String, String>();\n        Charset charset = Charset.forName(\"utf-8\");\n        int contentLength = -1;\n        SimpleHttpResponse response;\n        while (true) {\n            if (bg >= buf.length) {\n                throw new IndexOutOfBoundsException(\"buf index out of range: \" + bg + \", buf.length=\" + buf.length);\n            }\n            if ((len = in.read(buf, bg, buf.length - bg)) > 0) {\n                bg += len;\n                len = bg;\n                int idx;\n                int parseBg = 0;\n                while ((idx = indexOfCRLF(parseBg, len)) >= 0) {\n                    String line = new String(buf, parseBg, idx - parseBg, charset);\n                    parseBg = idx + 2;\n                    if (statusLine == null) {\n                        statusLine = line;\n                    } else {\n                        if (line.isEmpty()) {\n                            //When the `Content-Length` is absent, parse the rest of the bytes as body directly.\n                            //if (contentLength == -1) {\n                            //    contentLength = MAX_BODY_SIZE;\n                            //}\n","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/alibaba/Sentinel/blob/a3f40ba8e900c8489bd520274739f17235a7721c/sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/client/SimpleHttpResponseParser.java#L52-L88","documentation":"SimpleHttpResponseParser buffers the whole HTTP response in one byte[] of fixed capacity (default 4 KB). Before each socket read it checks bg >= buf.length and throws IndexOutOfBoundsException(\"buf index out of range: ...\") once the buffered bytes fill the buffer — meaning status line + headers (+ any early body) exceed the configured maxSize. This is a buffer-capacity failure, not a malformed-response failure.","triggerScenarios":"A heartbeat/dashboard HTTP response whose header block exceeds the buffer: e.g. response with many large Set-Cookie/Cache-Control headers from a proxy or gateway in front of the Sentinel dashboard, read into the default 4 KB parser buffer.","commonSituations":"Corporate proxies, load balancers, or WAFs injecting large header sets (cookies, tracing headers) inflating responses past 4 KB; dashboard responses growing after a version upgrade; using the default parser against an endpoint that returns big headers.","solutions":["Construct the parser with a larger buffer: new SimpleHttpResponseParser(64 * 1024)","Remove the proxy/gateway hop in front of the dashboard so heartbeat responses stay small","Strip heavy response headers at the intermediary (e.g. proxy_ignore_headers / header size limits reversed)"],"exampleFix":"// before\nparser = new SimpleHttpResponseParser(); // 4KB buffer\n\n// after\nparser = new SimpleHttpResponseParser(64 * 1024);","handlingStrategy":"validation","validationCode":"// size the buffer to the largest expected header block before parsing\nint bufSize = Math.max(16 * 1024, expectedMaxHeaderBytes);\nSimpleHttpResponseParser parser = new SimpleHttpResponseParser(bufSize);","typeGuard":null,"tryCatchPattern":"try {\n    response = parser.parse(in);\n} catch (IndexOutOfBoundsException e) {\n    // headers exceeded buffer: retry once with a doubled buffer on a fresh connection\n    response = new SimpleHttpResponseParser(bufSize * 2).parse(reopen(in));\n}","preventionTips":["Provision 32-64KB parser buffers when proxies inject large headers","Monitor for this exception as a signal of header bloat from intermediaries"],"tags":["sentinel","transport","http","buffer-overflow","simple-http"],"backgroundTag":null,"analyzedSha":"a3f40ba8e900c8489bd520274739f17235a7721c","analyzedAt":"2026-08-14T11:10:30.678Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}