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 drained successfully but its bytes failed to decode in BinaryImageDecoder (Imagick::readImageBlob). Root causes are identical to reading binary data directly; the message already guesses 'unsupported image format', but truncated content is equally common. The original DecoderException is discarded, so no detail survives.

Source

Thrown at src/Drivers/Imagick/Decoders/StreamImageDecoder.php:61

        $contents = '';
        $rewind = rewind($input);
        if ($rewind === 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. Drain and sniff the bytes first: finfo_buffer() on stream_get_contents() to confirm actual image data
  2. Verify upload completeness (Content-Length vs actual bytes) before decoding
  3. Check Imagick::queryFormats() for the target format and install missing delegates
  4. Re-fetch or re-upload the source when the body is truncated

Example fix

// before
$image = $manager->read(fopen('php://input', 'rb')); // partial body -> generic failure

// after
$contents = file_get_contents('php://input');
if (strlen($contents) < (int) ($_SERVER['CONTENT_LENGTH'] ?? 0)) {
    throw new RuntimeException('Upload incomplete');
}
$image = $manager->read($contents);
Defensive patterns

Strategy: validation

Validate before calling

$contents = stream_get_contents($stream);
$mime = finfo_buffer(finfo_open(FILEINFO_MIME_TYPE), $contents);
if (!str_starts_with((string) $mime, 'image/')) {
    throw new RuntimeException('Stream did not contain image data');
}
$image = $manager->read($contents);

Try / catch

try {
    $image = $manager->read($stream);
} catch (\Intervention\Image\Exceptions\ImageDecoderException $e) {
    $logger->warning('Stream payload undecodable: ' . $e->getMessage());
    throw $e;
}

Prevention

When it happens

Trigger: ImageManager::read(fopen($path, 'rb')) where the file is corrupt or the format lacks a delegate; reading php://input when the request body is only partially uploaded; stream wrappers over remote resources returning error pages.

Common situations: Upload endpoints streaming request bodies straight into the manager; WebP/AVIF sources on hosts without delegates; interrupted transfers leaving short bodies.

Understand the failure class

Related errors


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