guzzle/guzzle · error · \RuntimeException

value is not a non-negative decimal integer

Error message

value is not a non-negative decimal integer

What it means

Thrown by HeaderProcessor::parseContentLength() when any comma-separated part of a Content-Length value fails the ^[0-9]+$ check. Content-Length must be a single non-negative decimal integer per RFC 7230; anything else (a float, a sign, text) is rejected as an anti-smuggling measure. Raised as \RuntimeException.

Source

Thrown at src/Handler/HeaderProcessor.php:114

        return \preg_match('/^[\x20\x09\x21-\x7E\x80-\xFF]*(?:\r\n|\r|\n)?$/D', \trim($parts[1], " \t")) === 1;
    }

    /**
     * Returns a normalized decimal Content-Length, or null when absent.
     *
     * @param string[] $values
     *
     * @throws \RuntimeException when Content-Length is malformed or conflicting.
     */
    public static function parseContentLength(array $values): ?string
    {
        $length = null;

        foreach ($values as $value) {
            foreach (\explode(',', $value) as $part) {
                $part = \trim($part, " \t");
                if (\preg_match('/^[0-9]+$/D', $part) !== 1) {
                    throw new \RuntimeException('value is not a non-negative decimal integer');
                }

                $part = \ltrim($part, '0');
                $part = $part === '' ? '0' : $part;
                if ($length !== null && $part !== $length) {
                    throw new \RuntimeException('values conflict');
                }

                $length = $part;
            }
        }

        if ($length === null) {
            return null;
        }

        return $length;
    }

View on GitHub (pinned to 9b200fc580)

Solutions

  1. Capture the response headers to confirm the malformed Content-Length value
  2. Fix the origin server or the intermediary that produced it
  3. try/catch the request to handle the malformed response defensively

Example fix

try {
    $resp = $client->get($url);
} catch (\RuntimeException $e) {
    if (str_contains($e->getMessage(), 'non-negative decimal integer')) {
        // server sent an invalid Content-Length
    }
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    $response = $client->request('GET', $url);
} catch (\RuntimeException $e) {
    if (str_contains($e->getMessage(), 'non-negative decimal integer')) {
        // server returned an invalid Content-Length
    }
}

Prevention

When it happens

Trigger: The server (or an intermediary) returns 'Content-Length: 1.0', 'Content-Length: -5', 'Content-Length: abc', or a quoted value. Any handler path that parses response Content-Length hits it.

Common situations: A buggy origin that sends a float Content-Length, a proxy that rewrites headers incorrectly, or a chunked response where a middlebox injected a bad Content-Length.

Related errors


AI-assisted analysis of guzzle/guzzle@9b200fc580 (2026-08-04). Data as JSON: /data/errors/7be6800f840fd28c.json. Report an issue: GitHub.