Intervention/image · error · ImageDecoderException

Failed to read media (MIME) type from data in file path

Error message

Failed to read media (MIME) type from data in file path

What it means

This is the fallback path of mediaTypeByFilePath(): either the fileinfo extension is unavailable (finfo_file/finfo_open missing) or it returned a non-string, so the decoder falls back to @getimagesize() — and that also failed to produce its info array. Combined, the file's type could not be determined at all: typically the data is not an image, is truncated/corrupt, or is unreadable despite passing the earlier readable-file check.

Source

Thrown at src/Drivers/Gd/Decoders/AbstractDecoder.php:52

    protected function mediaTypeByFilePath(string $filepath): MediaType
    {
        $filepath = self::readableFilePathOrFail($filepath);

        if (function_exists('finfo_file') && function_exists('finfo_open')) {
            $mediaType = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $filepath);
            if (is_string($mediaType)) {
                try {
                    return MediaType::from($mediaType);
                } catch (ValueError | TypeError) {
                    throw new NotSupportedException('Unsupported media type (MIME) ' . $mediaType . '.');
                }
            }
        }

        $info = @getimagesize($filepath);

        if (!is_array($info)) {
            throw new ImageDecoderException('Failed to read media (MIME) type from data in file path');
        }

        try {
            return MediaType::from($info['mime']);
        } catch (ValueError | TypeError) {
            throw new NotSupportedException('Unsupported media type (MIME) ' . $info['mime'] . '.');
        }
    }

    /**
     * Return media (mime) type of the given image data
     *
     * @throws ImageDecoderException
     * @throws NotSupportedException
     */
    protected function mediaTypeByBinary(string $data): MediaType
    {
        if (function_exists('finfo_buffer') && function_exists('finfo_open')) {

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Install/enable ext-fileinfo: docker-php-ext-install fileinfo (or apt install php8.x-fileinfo) so the robust finfo path is used
  2. Verify the payload is really an image before read(): getimagesize($path) !== false, or check the magic bytes yourself
  3. If the file is a partial download, re-fetch it completely (compare Content-Length) before processing
  4. Log the first bytes (bin2hex(substr((string) file_get_contents($path), 0, 16))) to identify what actually arrived

Example fix

// before
$image = $manager->read($downloadedPath); // ImageDecoderException

// after
if (@getimagesize($downloadedPath) === false) {
    throw new RuntimeException('Downloaded file is not a valid image');
}
$image = $manager->read($downloadedPath);
Defensive patterns

Strategy: validation

Validate before calling

$isImage = function (string $path): bool {
    if (!is_file($path) || filesize($path) === 0) {
        return false;
    }
    if (function_exists('finfo_file')) {
        return str_starts_with(
            (string) finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path),
            'image/'
        );
    }

    return @getimagesize($path) !== false;
};

Try / catch

use Intervention\Image\Exceptions\ImageDecoderException;

try {
    $image = $manager->read($path);
} catch (ImageDecoderException $e) {
    // not decodable as an image: log payload head and reject
    logger()->warning('Non-image payload: ' . bin2hex((string) substr((string) file_get_contents($path), 0, 16)));
    throw $e;
}

Prevention

When it happens

Trigger: Reading a non-image file (HTML/JSON error body cached as .jpg); zero-byte or truncated upload; PHP built without ext-fileinfo (minimal Docker images, --disable-fileinfo builds); getimagesize() failing on formats it does not recognize.

Common situations: Download pipelines saving API error pages with image extensions; slim/alpine PHP images lacking fileinfo so getimagesize() alone must judge corrupt files; CDNs serving partial content.

Related errors


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