Intervention/image · error · EncoderException

Failed to encode png format

Error message

Failed to encode png format

What it means

The Imagick driver's PngEncoder has two paths: an indexed path that reduces colors to 256 then sets format 'PNG', and a default path setting format 'PNG32'; both set ZIP compression and optionally INTERLACE_LINE (src/Drivers/Imagick/Encoders/PngEncoder.php:33-53) before getImagesBlob(). Any ImagickException is rethrown as EncoderException ('Failed to encode png format') with the original as previous. PNG coders are universally available, so failures point at resource exhaustion (large indexed conversions), ancient builds without the PNG32 subformat, or policy.xml limits.

Source

Thrown at src/Drivers/Imagick/Encoders/PngEncoder.php:60

            } else {
                $output = clone $image->core()->native();
                $output->setFormat('PNG32');
                $output->setImageFormat('PNG32');
            }

            $output->setCompression(Imagick::COMPRESSION_ZIP);
            $output->setImageCompression(Imagick::COMPRESSION_ZIP);

            if ($this->interlaced) {
                $output->setInterlaceScheme(Imagick::INTERLACE_LINE);
            }

            $result = new EncodedImage($output->getImagesBlob(), 'image/png');
            $output->clear();

            return $result;
        } catch (ImagickException $e) {
            throw new EncoderException('Failed to encode png format', previous: $e);
        }
    }
}

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Read $e->getPrevious()->getMessage() for the underlying ImageMagick error.
  2. If using indexed: true on large images, encode non-indexed first to confirm the color-reduction step is the culprit, and downscale the source.
  3. Raise PHP memory_limit and ImageMagick policy.xml area/memory limits.
  4. On ancient builds, upgrade ImageMagick/imagick so the PNG32 subformat exists.

Example fix

// before
$encoded = $manager->read('poster-12000px.png')->toPng(indexed: true);

// after
$encoded = $manager->read('poster-12000px.png')
    ->scaleDown(2048, 2048)
    ->toPng(indexed: true);
Defensive patterns

Strategy: try-catch

Try / catch

try {
    $encoded = $image->toPng(indexed: true);
} catch (EncoderException $e) {
    $reason = $e->getPrevious()?->getMessage() ?? $e->getMessage();
    $encoded = $image->toPng(); // retry without indexed/interlace options, then log $reason
}

Prevention

When it happens

Trigger: Calling toPng() with indexed: true (reduceColors(256) over a huge image inside the try block at PngEncoder.php:34-41), with interlaced: true, or on very large images where getImagesBlob() exceeds memory/policy limits. Rarely, setFormat('PNG32') fails on builds lacking the PNG32 subformat.

Common situations: Generating indexed/palette PNG thumbnails from high-resolution sources under tight memory_limit; policy.xml capped environments; old ImageMagick 6.7-era builds; batch jobs that accumulate Imagick objects and fragment memory.

Related errors


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