{"record":{"id":"31c6996f3c324929","repo":"Intervention/image","slug":"failed-to-rewind-position-of-stream-31c699","errorCode":null,"errorMessage":"Failed to rewind position of stream","messagePattern":"Failed to rewind position of stream","errorType":"exception","errorClass":"StreamException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Imagick/Decoders/StreamImageDecoder.php","lineNumber":46,"sourceCode":"     * {@inheritdoc}\n     *\n     * @see DecoderInterface::decode()\n     *\n     * @throws InvalidArgumentException\n     * @throws StreamException\n     * @throws DriverException\n     * @throws StateException\n     */\n    public function decode(mixed $input): ImageInterface\n    {\n        if (!is_resource($input) || !in_array(get_resource_type($input), ['file', 'stream'])) {\n            throw new InvalidArgumentException('Image source must be a resource of type \"file\" or \"stream\"');\n        }\n\n        $contents = '';\n        $rewind = rewind($input);\n        if ($rewind === false) {\n            throw new StreamException('Failed to rewind position of stream');\n        }\n\n        while (!feof($input)) {\n            $chunk = fread($input, 1024);\n            if ($chunk === false) {\n                throw new StreamException('Failed to read image from stream');\n            }\n\n            $contents .= $chunk;\n        }\n\n        try {\n            return parent::decode($contents);\n        } catch (DecoderException) {\n            throw new ImageDecoderException(\n                'Failed to decode image from stream, could be unsupported image format',\n            );\n        }","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Imagick/Decoders/StreamImageDecoder.php#L28-L64","documentation":"Before draining the stream the decoder rewinds it to position 0; rewind() returned false. This happens on non-seekable streams (pipes, sockets, custom wrappers without seek support) or streams whose underlying handle is gone. It is a StreamException (FilesystemException family), thrown before any decoding starts.","triggerScenarios":"Passing a pipe from popen()/proc_open(), the STDIN constant, a socket stream from fsockopen(), or a custom stream wrapper that does not implement seekable reads.","commonSituations":"CLI tools reading images from stdin; fetching from network sockets; stream wrappers over HTTP that only support sequential reads.","solutions":["Buffer non-seekable streams first and pass the bytes: $manager->read(stream_get_contents($input))","Or copy into a seekable buffer: $tmp = fopen('php://temp', 'r+b'); stream_copy_to_stream($input, $tmp); then pass $tmp","Check stream_get_meta_data($input)['seekable'] before handing the stream over"],"exampleFix":"// before\n$image = $manager->read(STDIN); // pipe is not rewindable -> StreamException\n\n// after\n$image = $manager->read(stream_get_contents(STDIN)); // pass bytes as binary string","handlingStrategy":"validation","validationCode":"$meta = stream_get_meta_data($stream);\nif (!$meta['seekable']) {\n    $stream = fopen('php://temp', 'r+b');\n    stream_copy_to_stream($original, $stream);\n}\n$image = $manager->read($stream);","typeGuard":"function isSeekableFileStream(mixed $value): bool\n{\n    return is_resource($value)\n        && in_array(get_resource_type($value), ['file', 'stream'], true)\n        && stream_get_meta_data($value)['seekable'] === true;\n}","tryCatchPattern":null,"preventionTips":["Never feed pipes/sockets/STDIN directly - buffer with stream_get_contents() first","Check stream_get_meta_data()['seekable'] before handing streams to image code"],"tags":["stream","rewind","non-seekable","pipe"],"backgroundTag":"stream-not-seekable","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}