alibaba/Sentinel · error · IndexOutOfBoundsException

buf index out of range: {bg}, buf.length={len}

Error message

buf index out of range: {bg}, buf.length={len}

What it means

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.

Source

Thrown at sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/client/SimpleHttpResponseParser.java:70

    /**
     * Parse bytes from an input stream to a {@link SimpleHttpResponse}.
     *
     * @param in input stream
     * @return parsed HTTP response entity
     * @throws IOException when an IO error occurs
     */
    public SimpleHttpResponse parse(InputStream in) throws IOException {
        int bg = 0;
        int len;
        String statusLine = null;
        Map<String, String> headers = new HashMap<String, String>();
        Charset charset = Charset.forName("utf-8");
        int contentLength = -1;
        SimpleHttpResponse response;
        while (true) {
            if (bg >= buf.length) {
                throw new IndexOutOfBoundsException("buf index out of range: " + bg + ", buf.length=" + buf.length);
            }
            if ((len = in.read(buf, bg, buf.length - bg)) > 0) {
                bg += len;
                len = bg;
                int idx;
                int parseBg = 0;
                while ((idx = indexOfCRLF(parseBg, len)) >= 0) {
                    String line = new String(buf, parseBg, idx - parseBg, charset);
                    parseBg = idx + 2;
                    if (statusLine == null) {
                        statusLine = line;
                    } else {
                        if (line.isEmpty()) {
                            //When the `Content-Length` is absent, parse the rest of the bytes as body directly.
                            //if (contentLength == -1) {
                            //    contentLength = MAX_BODY_SIZE;
                            //}

View on GitHub (pinned to a3f40ba8e9)

Solutions

  1. Construct the parser with a larger buffer: new SimpleHttpResponseParser(64 * 1024)
  2. Remove the proxy/gateway hop in front of the dashboard so heartbeat responses stay small
  3. Strip heavy response headers at the intermediary (e.g. proxy_ignore_headers / header size limits reversed)

Example fix

// before
parser = new SimpleHttpResponseParser(); // 4KB buffer

// after
parser = new SimpleHttpResponseParser(64 * 1024);
Defensive patterns

Strategy: validation

Validate before calling

// size the buffer to the largest expected header block before parsing
int bufSize = Math.max(16 * 1024, expectedMaxHeaderBytes);
SimpleHttpResponseParser parser = new SimpleHttpResponseParser(bufSize);

Try / catch

try {
    response = parser.parse(in);
} catch (IndexOutOfBoundsException e) {
    // headers exceeded buffer: retry once with a doubled buffer on a fresh connection
    response = new SimpleHttpResponseParser(bufSize * 2).parse(reopen(in));
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of alibaba/Sentinel@a3f40ba8e9 (2026-08-14). Data as JSON: /api/errors/eb961ff0d747a69a. Report an issue: GitHub.