guzzle/guzzle · error · \RuntimeException
A response must not contain both Content-Length and Transfer
Error message
A response must not contain both Content-Length and Transfer-Encoding
What it means
Thrown by HeaderProcessor::validateResponseFraming() when a response that can carry a body has both a Content-Length and a Transfer-Encoding header. RFC 7230 forbids the combination and it is a classic request/response-smuggling signal, so Guzzle rejects it outright. \RuntimeException.
Source
Thrown at src/Handler/HeaderProcessor.php:188
string $method,
int $status,
array $headers
): ?string {
if (!self::responseCanHaveBody($method, $status)) {
return null;
}
$normalizedKeys = Utils::normalizeHeaderKeys($headers);
$contentLength = self::removeHeader('Content-Length', $headers);
try {
$length = self::parseContentLength($contentLength);
} catch (\RuntimeException $e) {
throw new \RuntimeException('Invalid Content-Length response header: '.$e->getMessage(), 0, $e);
}
if ($length !== null && isset($normalizedKeys['transfer-encoding'])) {
throw new \RuntimeException('A response must not contain both Content-Length and Transfer-Encoding');
}
return $length;
}
/**
* Removes every case-insensitive occurrence of a header and returns all
* removed values in their original field order.
*
* @param array<string, string[]> $headers
*
* @return string[] Removed values across all header-name casings
*/
public static function removeHeader(string $name, array &$headers): array
{
$values = [];
foreach ($headers as $key => $headerValues) {View on GitHub (pinned to 9b200fc580)
Solutions
- Inspect the response headers for the simultaneous CL + TE pair
- Fix the intermediary so it strips one (chunked responses should not carry Content-Length)
- try/catch the request to handle the framing conflict defensively
Defensive patterns
Strategy: try-catch
Try / catch
try {
$response = $client->request('GET', $url);
} catch (\RuntimeException $e) {
if (str_contains($e->getMessage(), 'both Content-Length and Transfer-Encoding')) {
// framing conflict — fix the origin/proxy that emits both
}
} Prevention
- Configure proxies to strip Content-Length when applying chunked encoding
- Treat this error as a potential smuggling signal in production
- Audit CDN/intermediary header handling during integration
When it happens
Trigger: The origin or a proxy chain sends both 'Content-Length' and 'Transfer-Encoding' on the same response (e.g. 'Transfer-Encoding: chunked' plus a stale Content-Length).
Common situations: Misconfigured reverse proxy/CDN that forwards both headers, an older intermediary, or a deliberate smuggling attempt.
Related errors
- values conflict
- A request must not contain both Content-Length and Transfer-
- value is not a non-negative decimal integer
- Invalid Content-Length response header: {reason}
- headers must be an array
AI-assisted analysis of guzzle/guzzle@9b200fc580 (2026-08-04).
Data as JSON: /data/errors/ea4fdeb2c2fa6021.json.
Report an issue: GitHub.