Intervention/image · error · ImageDecoderException

Failed to decode image from stream, could be unsupported ima

Error message

Failed to decode image from stream, could be unsupported image format

What it means

The stream was read fully into memory, but no decoder in the GD chain could interpret the bytes, so the generic DecoderException is rethrown as ImageDecoderException with the 'could be unsupported image format' hint. The problem is the content, not the stream handling.

Source

Thrown at src/Drivers/Gd/Decoders/StreamImageDecoder.php:65

        $result = rewind($input);

        if ($result === false) {
            throw new StreamException('Failed to rewind position of stream');
        }

        while (!feof($input)) {
            $chunk = fread($input, 1024);
            if ($chunk === false) {
                throw new StreamException('Failed to read image from stream');
            }

            $contents .= $chunk;
        }

        try {
            return parent::decode($contents);
        } catch (DecoderException) {
            throw new ImageDecoderException(
                'Failed to decode image from stream, could be unsupported image format',
            );
        }
    }
}

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Sniff the buffered content with (new finfo())->buffer($contents) before decoding
  2. Check gd_info() for the required format support in that environment
  3. Switch to the Imagick driver for broader format coverage
  4. Catch ImageDecoderException and reject the source with a clear upstream error

Example fix

// before
$image = $manager->decodeStream($socketStream);

// after
$contents = stream_get_contents($socketStream);
$mime = (new finfo())->buffer($contents);
if (!str_starts_with($mime, 'image/')) {
    throw new RuntimeException('Stream did not contain an image: ' . $mime);
}
$image = $manager->read($contents);
Defensive patterns

Strategy: try-catch

Validate before calling

$contents = stream_get_contents($fp);
if (!str_starts_with((new finfo())->buffer($contents), 'image/')) {
    throw new RuntimeException('Stream content is not an image');
}
$manager->read($contents);

Try / catch

try {
    $image = $manager->decodeStream($fp);
} catch (ImageDecoderException $e) {
    // sniff buffered content, then reject or fall back to Imagick driver
}

Prevention

When it happens

Trigger: Streaming WebP or AVIF bytes into a GD build without that format support; binary garbage (archives, encrypted payloads) fed as an image stream; a truncated file that still finished reading.

Common situations: Microservices receiving image bytes over queues or sockets without MIME validation, GD builds missing webp on older distros, processing files by naming convention instead of sniffing content.

Understand the failure class

Related errors


AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23). Data as JSON: /api/errors/1e3be54c66a50d49. Report an issue: GitHub.