Intervention/image · info · AnalyzerException

Input must be PNG format

Error message

Input must be PNG format

What it means

The third resolution-recovery strategy reads the first 8 bytes of the origin stream and compares them against the exact PNG signature \x89PNG\x0D\x0A\x1A\x0A. Any mismatch throws this AnalyzerException and ends the PNG branch. It is an internal precondition check — a non-PNG file simply cannot contain a pHYs chunk — and the exception is swallowed by the surrounding recovery chain.

Source

Thrown at src/Drivers/Gd/Analyzers/ResolutionAnalyzer.php:188

            }

            return $values[0] / $values[1];
        }, $resolution);
    }

    /**
     * @param resource $handle
     * @throws AnalyzerException
     * @return array<float>
     */
    private function resolutionFromPngPhys($handle): array
    {
        rewind($handle);
        $signature = fread($handle, 8);

        // no PNG content
        if ($signature !== "\x89PNG\x0D\x0A\x1A\x0A") {
            throw new AnalyzerException('Input must be PNG format');
        }

        $marker = '';

        while (!feof($handle)) {
            $marker = strlen($marker) < 4 ? $marker . fread($handle, 1) : substr($marker, 1) . fread($handle, 1);

            // find pHYs chunk
            if ($marker === 'pHYs') {
                // find length
                fseek($handle, -8, SEEK_CUR);
                $length = fread($handle, 4);
                $length = unpack('N', $length)[1];
                fseek($handle, 4, SEEK_CUR);

                // pHYs chunk must be exactly 9 bytes
                if ($length !== 9) {
                    throw new AnalyzerException('Invalid pHYs chunk length');

View on GitHub (pinned to 5598b9e397)

Solutions

  1. No action needed: non-PNG origins are expected here and the analyzer falls back to 96 DPI
  2. If you expected PNG data, verify the signature yourself: bin2hex(substr($data, 0, 8)) === '89504e470d0a1a0a'
  3. Convert the file to real PNG before processing if pHYs density matters
Defensive patterns

Strategy: validation

Validate before calling

$signature = (string) fread($handle, 8);
rewind($handle);
$isPng = $signature === "\x89PNG\x0D\x0A\x1A\x0A";

Prevention

When it happens

Trigger: A JPEG, WebP, GIF, or arbitrary binary reaching resolutionFromPngPhys() after the JFIF and EXIF parsers both failed; files renamed to .png without being converted.

Common situations: Extension/mime mismatch uploads; recovery order placing PNG parsing last means every non-PNG origin without JFIF/EXIF density hits this path silently.

Related errors


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