{"record":{"id":"471dc9503d0ba0af","repo":"alibaba/Sentinel","slug":"invalid-content-length-contentlength","errorCode":null,"errorMessage":"Invalid content length: {contentLength}","messagePattern":"Invalid content length: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/client/SimpleHttpResponseParser.java","lineNumber":98,"sourceCode":"                    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\n                            // Parse HTTP body.\n                            // When the `Content-Length` is absent, drop the body, return directly.\n                            response = new SimpleHttpResponse(statusLine, headers);\n                            if (contentLength <= 0) {\n                                return response;\n                            }\n                            ByteArrayOutputStream out = new ByteArrayOutputStream(1024);\n                            // `Content-Length` is not equal to exact length.\n                            if (contentLength < len - parseBg) {\n                                throw new IllegalStateException(\"Invalid content length: \" + contentLength);\n                            }\n                            out.write(buf, parseBg, len - parseBg);\n                            if (out.size() > MAX_BODY_SIZE) {\n                                throw new IllegalStateException(\n                                    \"Request body is too big, limit size is \" + MAX_BODY_SIZE);\n                            }\n                            int cap = Math.min(contentLength - out.size(), buf.length);\n                            while (cap > 0 && (len = in.read(buf, 0, cap)) > 0) {\n                                out.write(buf, 0, len);\n                                cap = Math.min(contentLength - out.size(), buf.length);\n                            }\n                            response.setBody(out.toByteArray());\n                            return response;\n                        } else if (!line.trim().isEmpty()) {\n                            // Parse HTTP header.\n                            int idx2 = line.indexOf(\":\");\n                            String key = line.substring(0, idx2).trim();\n                            String value = line.substring(idx2 + 1).trim();","sourceCodeStart":80,"sourceCodeEnd":116,"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#L80-L116","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the server to send an accurate Content-Length equal to the exact byte length of the body","Compute the length after serialization: byte[] body = json.getBytes(UTF_8); set header to body.length","Remove body-rewriting intermediaries between the client and the dashboard"],"exampleFix":"// before (dashboard/servlet)\nString json = toJson(obj);\nresp.setHeader(\"Content-Length\", String.valueOf(json.length())); // chars, not bytes\n\n// after\nbyte[] json = toJson(obj).getBytes(StandardCharsets.UTF_8);\nresp.setHeader(\"Content-Length\", String.valueOf(json.length));\nresp.getOutputStream().write(json);","handlingStrategy":"fallback","validationCode":"// server-side prevention: compute Content-Length from serialized bytes\nbyte[] body = json.getBytes(StandardCharsets.UTF_8);\nexchange.getResponseHeaders().set(\"Content-Length\", String.valueOf(body.length));","typeGuard":null,"tryCatchPattern":"try {\n    response = parser.parse(in);\n} catch (IllegalStateException e) { // 'Invalid content length'\n    // server sent inconsistent headers; treat response as unusable, do not retry blindly\n    log.warn(\"Inconsistent Content-Length from {} : {}\", url, e.getMessage());\n}","preventionTips":["Compute Content-Length after full serialization, in bytes not chars","Keep intermediaries from rewriting response bodies"],"tags":["sentinel","transport","http","protocol-error","content-length"],"backgroundTag":null,"analyzedSha":"a3f40ba8e900c8489bd520274739f17235a7721c","analyzedAt":"2026-08-14T11:10:30.678Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}