{"record":{"id":"1cebd87d8b27b88d","repo":"guzzle/guzzle","slug":"the-request-body-position-is-outside-the-stream-si","errorCode":null,"errorMessage":"The request body position is outside the stream size","messagePattern":"The request body position is outside the stream size","errorType":"exception","errorClass":"GuzzleHttp\\Exception\\RequestException","httpStatus":null,"severity":"error","filePath":"src/Handler/RequestFraming.php","lineNumber":162,"sourceCode":"                $request,\n                $e,\n                'Timed out while determining the request body size',\n                'Failed to determine the request body size'\n            );\n        }\n\n        if ($seekable) {\n            return $size;\n        }\n\n        try {\n            $position = $body->tell();\n        } catch (\\RuntimeException $e) {\n            return null;\n        }\n\n        if ($position < 0 || $position > $size) {\n            throw new RequestException('The request body position is outside the stream size', $request);\n        }\n\n        return $size - $position;\n    }\n\n    /**\n     * Materializes the body, stopping at the selected Content-Length when\n     * present.\n     *\n     * @throws RequestException when the body cannot be fully rewound or read\n     */\n    public function materialize(): string\n    {\n        $body = $this->request->getBody();\n\n        if ($this->contentLength === null) {\n            try {\n                return (string) $body;","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/guzzle/guzzle/blob/d1cbca76970939a9c2ced55b1e25ea26f34fc773/src/Handler/RequestFraming.php#L144-L180","documentation":"Thrown by RequestFraming::bodySize() as a RequestException when a non-seekable body stream's tell() reports a position that is negative or greater than the stream's total size. The available byte count is computed as size - position; an out-of-range position makes that meaningless, so the handler rejects it before dispatch.","triggerScenarios":"A request body that is a non-seekable stream whose current position is inconsistent with its reported size (position < 0 or position > size). bodySize() reads tell() only for non-seekable streams and validates the range.","commonSituations":"A custom StreamInterface that returns inconsistent tell()/getSize(), a pipe/socket stream whose position accounting is broken, or a stream that was partially consumed and rewound incorrectly. Bugs in a decorated stream wrapper.","solutions":["Use a seekable stream (e.g. GuzzleHttp\\Psr7\\Utils::streamFor($string)) so position is handled by rewind.","Fix the custom stream's tell() and getSize() to return consistent, monotonic values.","Wrap the body in a buffered stream and reset its position to 0 before assigning.","If the source is php://input or a pipe, read it fully into a seekable buffer first."],"exampleFix":"// before\n$request = new Request('POST', '/u', [], $brokenNonSeekableStream); // tell() > size\n\n// after\n$buffer = \\GuzzleHttp\\Psr7\\Utils::streamFor((string) $brokenNonSeekableStream);\n$request = new Request('POST', '/u', [], $buffer);","handlingStrategy":"validation","validationCode":"$body = $request->getBody();\nif (!$body->isSeekable()) {\n    $size = $body->getSize();\n    try {\n        $pos = $body->tell();\n    } catch (\\RuntimeException $e) {\n        $pos = null;\n    }\n    if ($pos !== null && ($pos < 0 || $pos > $size)) {\n        throw new \\InvalidArgumentException('Body position is outside the stream size');\n    }\n}","typeGuard":"function bodyPositionIsConsistent(\\Psr\\Http\\Message\\StreamInterface $s): bool {\n    if ($s->isSeekable()) {\n        return true;\n    }\n    try {\n        $pos = $s->tell();\n    } catch (\\RuntimeException $e) {\n        return true;\n    }\n    return $pos >= 0 && $pos <= $s->getSize();\n}","tryCatchPattern":null,"preventionTips":["Use seekable streams for request bodies","Wrap pipes/inputs in a buffered seekable stream","Keep custom StreamInterface tell()/getSize() consistent and monotonic"],"tags":["request","body","stream","validation","framing","seekable"],"backgroundTag":null,"analyzedSha":"d1cbca76970939a9c2ced55b1e25ea26f34fc773","analyzedAt":"2026-08-06T00:37:27.795Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}