{"record":{"id":"3cd02b4eacd65114","repo":"Intervention/image","slug":"failed-to-convert-font-to-imagickdraw-instance","errorCode":null,"errorMessage":"Failed to convert font to ImagickDraw instance","messagePattern":"Failed to convert font to ImagickDraw instance","errorType":"exception","errorClass":"DriverException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Imagick/FontProcessor.php","lineNumber":77,"sourceCode":"    public function toImagickDraw(FontInterface $font, ?ImagickPixel $color = null): ImagickDraw\n    {\n        if (!$font->hasFile()) {\n            throw new StateException('No font file specified');\n        }\n\n        try {\n            $draw = new ImagickDraw();\n            $draw->setStrokeAntialias(true);\n            $draw->setTextAntialias(true);\n            $draw->setFont($font->filepath());\n            $draw->setFontSize($this->nativeFontSize($font));\n            $draw->setTextAlignment(Imagick::ALIGN_LEFT);\n\n            if ($color instanceof ImagickPixel) {\n                $draw->setFillColor($color);\n            }\n        } catch (ImagickException | ImagickDrawException $e) {\n            throw new DriverException('Failed to convert font to ImagickDraw instance', previous: $e);\n        }\n\n        return $draw;\n    }\n}\n","sourceCodeStart":59,"sourceCodeEnd":83,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Imagick/FontProcessor.php#L59-L83","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use absolute paths for font files and verify with is_readable() before calling text()","Fix permissions for the runtime user (www-data, queue-worker) on the fonts directory","Confirm the file is really a font: file command, fc-scan, or finfo mime type","Exclude the fonts path from open_basedir restrictions if applicable"],"exampleFix":"// before\n$fontPath = 'fonts/arial.ttf'; // relative, breaks in other cwd\n$image->text($label, 50, 50, fn ($font) => $font->file($fontPath));\n\n// after\n$fontPath = realpath(__DIR__ . '/fonts/arial.ttf');\nif ($fontPath === false || !is_readable($fontPath)) {\n    throw new RuntimeException('Font file missing or unreadable');\n}\n$image->text($label, 50, 50, fn ($font) => $font->file($fontPath));","handlingStrategy":"validation","validationCode":"if (!is_string($fontPath) || !is_readable($fontPath)) {\n    throw new RuntimeException('Cannot read font file: ' . print_r($fontPath, true));\n}\n$mime = (new finfo(FILEINFO_MIME_TYPE))->file($fontPath);\nif (!str_starts_with($mime, 'font/')) {\n    throw new RuntimeException('Not a font file (mime ' . $mime . ')');\n}\n$image->text($label, $x, $y, fn ($font) => $font->file($fontPath));","typeGuard":null,"tryCatchPattern":"use Intervention\\Image\\Exceptions\\DriverException;\n\ntry {\n    $image->text($label, $x, $y, fn ($font) => $font->file($fontPath));\n} catch (DriverException $e) {\n    $reason = $e->getPrevious()?->getMessage() ?? '';\n    if (str_contains($reason, 'UnableToOpenFont') || str_contains(strtolower($reason), 'font')) {\n        throw new RuntimeException('Font failed to load from ' . $fontPath . ': ' . $reason, 0, $e);\n    }\n    throw $e;\n}","preventionTips":["Resolve font paths with realpath() at boot and cache the result","Make fonts readable by the PHP runtime user in Docker (COPY --chmod) and deploy scripts","Check finfo mime of uploaded fonts before storing them"],"tags":["imagick","font","file-not-found","permissions","text"],"backgroundTag":"font-file-load-failed","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}