Intervention/image · error · DriverException

Failed to convert font to ImagickDraw instance

Error message

Failed to convert font to ImagickDraw instance

What it means

While converting the Font into an ImagickDraw — setStrokeAntialias, setTextAntialias, setFont($font->filepath()), setFontSize, setTextAlignment, setFillColor (src/Drivers/Imagick/FontProcessor.php:66-75) — any ImagickException or ImagickDrawException is wrapped as DriverException. In practice setFont() fails when the file path does not exist, is unreadable, or is not a loadable font, so ImageMagick cannot open the font resource.

Source

Thrown at src/Drivers/Imagick/FontProcessor.php:77

    public function toImagickDraw(FontInterface $font, ?ImagickPixel $color = null): ImagickDraw
    {
        if (!$font->hasFile()) {
            throw new StateException('No font file specified');
        }

        try {
            $draw = new ImagickDraw();
            $draw->setStrokeAntialias(true);
            $draw->setTextAntialias(true);
            $draw->setFont($font->filepath());
            $draw->setFontSize($this->nativeFontSize($font));
            $draw->setTextAlignment(Imagick::ALIGN_LEFT);

            if ($color instanceof ImagickPixel) {
                $draw->setFillColor($color);
            }
        } catch (ImagickException | ImagickDrawException $e) {
            throw new DriverException('Failed to convert font to ImagickDraw instance', previous: $e);
        }

        return $draw;
    }
}

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Use absolute paths for font files and verify with is_readable() before calling text()
  2. Fix permissions for the runtime user (www-data, queue-worker) on the fonts directory
  3. Confirm the file is really a font: file command, fc-scan, or finfo mime type
  4. Exclude the fonts path from open_basedir restrictions if applicable

Example fix

// before
$fontPath = 'fonts/arial.ttf'; // relative, breaks in other cwd
$image->text($label, 50, 50, fn ($font) => $font->file($fontPath));

// after
$fontPath = realpath(__DIR__ . '/fonts/arial.ttf');
if ($fontPath === false || !is_readable($fontPath)) {
    throw new RuntimeException('Font file missing or unreadable');
}
$image->text($label, 50, 50, fn ($font) => $font->file($fontPath));
Defensive patterns

Strategy: validation

Validate before calling

if (!is_string($fontPath) || !is_readable($fontPath)) {
    throw new RuntimeException('Cannot read font file: ' . print_r($fontPath, true));
}
$mime = (new finfo(FILEINFO_MIME_TYPE))->file($fontPath);
if (!str_starts_with($mime, 'font/')) {
    throw new RuntimeException('Not a font file (mime ' . $mime . ')');
}
$image->text($label, $x, $y, fn ($font) => $font->file($fontPath));

Try / catch

use Intervention\Image\Exceptions\DriverException;

try {
    $image->text($label, $x, $y, fn ($font) => $font->file($fontPath));
} catch (DriverException $e) {
    $reason = $e->getPrevious()?->getMessage() ?? '';
    if (str_contains($reason, 'UnableToOpenFont') || str_contains(strtolower($reason), 'font')) {
        throw new RuntimeException('Font failed to load from ' . $fontPath . ': ' . $reason, 0, $e);
    }
    throw $e;
}

Prevention

When it happens

Trigger: text()/boxSize() with $font->file() pointing to a missing, moved, or permission-denied file; a file that exists but is not a font (mislabeled .ttf); open_basedir restrictions blocking the font location; temp font files deleted before use.

Common situations: Relative font paths that break when the working directory changes (queue workers, CLI, cron); fonts under storage/ not readable by www-data; deployment pipelines that skip the fonts directory; downloaded fonts truncated.

Related errors


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