Intervention/image · error · EncoderException

Failed to encode jxl format

Error message

Failed to encode jxl format

What it means

The Imagick driver's JxlEncoder clones the native Imagick object, sets format 'JXL' and the configured quality (src/Drivers/Imagick/Encoders/JxlEncoder.php:38-42), then serializes with getImagesBlob(). Any ImagickException or ImageException is rethrown as EncoderException ('Failed to encode jxl format') with the original as previous. JPEG XL is the newest codec here: it requires ImageMagick 7.1+ built with libjxl, which almost no default distro build has - the previous exception will say 'no encode delegate for this image format'.

Source

Thrown at src/Drivers/Imagick/Encoders/JxlEncoder.php:49

        // strip meta data
        if ($this->strip || (is_null($this->strip) && $this->driver()->config()->strip)) {
            $image->modify(new StripMetaModifier());
        }

        try {
            $imagick = clone $image->core()->native();
            $imagick->setFormat($format);
            $imagick->setImageFormat($format);
            $imagick->setCompressionQuality($this->quality);
            $imagick->setImageCompressionQuality($this->quality);

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

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

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Read $e->getPrevious()->getMessage() to confirm the missing-delegate error.
  2. Check Imagick::queryFormats('JXL') on the failing host and locally to see the capability gap.
  3. Build/install ImageMagick 7.1+ with the libjxl delegate (apt-get install libjxl-dev plus a linked build), then rebuild the imagick extension.
  4. Treat JXL as progressive enhancement: feature-detect at boot and fall back to toWebp() when the coder is missing.

Example fix

// before
$encoded = $manager->read('art.png')->toJxl();

// after
$jxlSupported = in_array('JXL', Imagick::queryFormats('JXL'), true);
$encoded = $jxlSupported ? $manager->read('art.png')->toJxl() : $manager->read('art.png')->toWebp();
Defensive patterns

Strategy: validation

Validate before calling

$jxlSupported = in_array('JXL', Imagick::queryFormats('JXL'), true);
if (!$jxlSupported) {
    throw new RuntimeException('JPEG XL encoding unavailable: ImageMagick 7.1+ with libjxl required');
}
$encoded = $image->toJxl();

Try / catch

try {
    $encoded = $image->toJxl();
} catch (EncoderException $e) {
    $reason = $e->getPrevious()?->getMessage() ?? $e->getMessage();
    $encoded = $image->toWebp(); // degrade, then log $reason
}

Prevention

When it happens

Trigger: Calling toJxl() on the Imagick driver when setFormat('JXL')/setImageFormat('JXL') throws because the JPEG XL coder is absent: php -r "var_dump((new Imagick())->queryFormats('JXL'));" returns an empty array. ImageMagick 6.x can never satisfy this call.

Common situations: Any Debian/Ubuntu/RHEL default ImageMagick package at the time JXL support was still uncommon; php Docker images; adopting JXL for bandwidth savings and discovering only the developer's locally compiled IM7 supports it.

Related errors


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