alibaba/Sentinel · error · IllegalStateException

Invalid content length: {contentLength}

Error message

Invalid content length: {contentLength}

What it means

While parsing a response body, SimpleHttpResponseParser first checks consistency: if the declared Content-Length is smaller than the number of body bytes already buffered from the header-read phase (contentLength < len - parseBg), it throws IllegalStateException("Invalid content length: ..."). This catches responses where the header claims fewer bytes than were actually sent — a protocol inconsistency that would otherwise cause a negative-length read.

Source

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

                    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;
                            //}

                            // Parse HTTP body.
                            // When the `Content-Length` is absent, drop the body, return directly.
                            response = new SimpleHttpResponse(statusLine, headers);
                            if (contentLength <= 0) {
                                return response;
                            }
                            ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
                            // `Content-Length` is not equal to exact length.
                            if (contentLength < len - parseBg) {
                                throw new IllegalStateException("Invalid content length: " + contentLength);
                            }
                            out.write(buf, parseBg, len - parseBg);
                            if (out.size() > MAX_BODY_SIZE) {
                                throw new IllegalStateException(
                                    "Request body is too big, limit size is " + MAX_BODY_SIZE);
                            }
                            int cap = Math.min(contentLength - out.size(), buf.length);
                            while (cap > 0 && (len = in.read(buf, 0, cap)) > 0) {
                                out.write(buf, 0, len);
                                cap = Math.min(contentLength - out.size(), buf.length);
                            }
                            response.setBody(out.toByteArray());
                            return response;
                        } else if (!line.trim().isEmpty()) {
                            // Parse HTTP header.
                            int idx2 = line.indexOf(":");
                            String key = line.substring(0, idx2).trim();
                            String value = line.substring(idx2 + 1).trim();

View on GitHub (pinned to a3f40ba8e9)

Solutions

  1. Fix the server to send an accurate Content-Length equal to the exact byte length of the body
  2. Compute the length after serialization: byte[] body = json.getBytes(UTF_8); set header to body.length
  3. Remove body-rewriting intermediaries between the client and the dashboard

Example fix

// before (dashboard/servlet)
String json = toJson(obj);
resp.setHeader("Content-Length", String.valueOf(json.length())); // chars, not bytes

// after
byte[] json = toJson(obj).getBytes(StandardCharsets.UTF_8);
resp.setHeader("Content-Length", String.valueOf(json.length));
resp.getOutputStream().write(json);
Defensive patterns

Strategy: fallback

Validate before calling

// server-side prevention: compute Content-Length from serialized bytes
byte[] body = json.getBytes(StandardCharsets.UTF_8);
exchange.getResponseHeaders().set("Content-Length", String.valueOf(body.length));

Try / catch

try {
    response = parser.parse(in);
} catch (IllegalStateException e) { // 'Invalid content length'
    // server sent inconsistent headers; treat response as unusable, do not retry blindly
    log.warn("Inconsistent Content-Length from {} : {}", url, e.getMessage());
}

Prevention

When it happens

Trigger: A server/proxy (custom dashboard endpoint or middleware in front of it) sending a Content-Length header smaller than the real body, e.g. hand-rolled HTTP responses that compute length before appending data; responses rewritten by a proxy that adds bytes (e.g. injected content) without updating Content-Length.

Common situations: Custom dashboard implementations computing Content-Length incorrectly (off-by-N, length computed in bytes vs chars with multibyte rules JSON); buggy proxies modifying bodies; test mocks with hardcoded wrong lengths.

Related errors


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