{"record":{"id":"ea4fdeb2c2fa6021","repo":"guzzle/guzzle","slug":"a-response-must-not-contain-both-content-length-an","errorCode":null,"errorMessage":"A response must not contain both Content-Length and Transfer-Encoding","messagePattern":"A response must not contain both Content-Length and Transfer-Encoding","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Handler/HeaderProcessor.php","lineNumber":188,"sourceCode":"        string $method,\n        int $status,\n        array $headers\n    ): ?string {\n        if (!self::responseCanHaveBody($method, $status)) {\n            return null;\n        }\n\n        $normalizedKeys = Utils::normalizeHeaderKeys($headers);\n        $contentLength = self::removeHeader('Content-Length', $headers);\n\n        try {\n            $length = self::parseContentLength($contentLength);\n        } catch (\\RuntimeException $e) {\n            throw new \\RuntimeException('Invalid Content-Length response header: '.$e->getMessage(), 0, $e);\n        }\n\n        if ($length !== null && isset($normalizedKeys['transfer-encoding'])) {\n            throw new \\RuntimeException('A response must not contain both Content-Length and Transfer-Encoding');\n        }\n\n        return $length;\n    }\n\n    /**\n     * Removes every case-insensitive occurrence of a header and returns all\n     * removed values in their original field order.\n     *\n     * @param array<string, string[]> $headers\n     *\n     * @return string[] Removed values across all header-name casings\n     */\n    public static function removeHeader(string $name, array &$headers): array\n    {\n        $values = [];\n\n        foreach ($headers as $key => $headerValues) {","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/guzzle/guzzle/blob/d1cbca76970939a9c2ced55b1e25ea26f34fc773/src/Handler/HeaderProcessor.php#L170-L206","documentation":"Thrown by HeaderProcessor::validateResponseFraming() when a body-bearing response carries both a Content-Length and a Transfer-Encoding header. RFC 7230 forbids this combination to prevent framing ambiguity and request/response smuggling; the presence of both is a protocol violation.","triggerScenarios":"A server returns headers like 'Transfer-Encoding: chunked' together with 'Content-Length: 123' on a response that can have a body. validateResponseFraming() detects the overlap after parsing a valid Content-Length and finding a transfer-encoding key.","commonSituations":"A proxy adds Transfer-Encoding: chunked but does not strip the origin's Content-Length (or vice versa), a misconfigured reverse proxy, or a deliberately non-conformant test server.","solutions":["Capture raw response headers (curl -v) to confirm both headers are present.","Fix the proxy/gateway to strip one header per RFC 7230 (prefer Transfer-Encoding when chunked).","If the server is out of your control, catch RuntimeException and decide whether to retry without strict framing.","Report the violation to the server operator."],"exampleFix":"// before - blind call to a non-conformant server\n$resp = $client->get($url);\n\n// after - tolerate the broken endpoint\ntry {\n    $resp = $client->get($url);\n} catch (\\RuntimeException $e) {\n    if (str_contains($e->getMessage(), 'both Content-Length and Transfer-Encoding')) {\n        // fall back, log, or use a different endpoint\n    }\n    throw $e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    $response = $client->get($url);\n} catch (\\RuntimeException $e) {\n    if (str_contains($e->getMessage(), 'both Content-Length and Transfer-Encoding')) {\n        // non-conformant server; fall back or report\n    }\n    throw $e;\n}","preventionTips":["Audit reverse proxies/gateways to strip one of the two headers per RFC 7230.","Use curl -v to detect the dual-header condition on the wire.","Avoid intermediaries that re-chunk without removing Content-Length."],"tags":["http","transfer-encoding","content-length","security","request-smuggling","php","guzzle"],"backgroundTag":null,"analyzedSha":"d1cbca76970939a9c2ced55b1e25ea26f34fc773","analyzedAt":"2026-08-06T00:37:27.795Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}