Intervention/image · error · StateException
The stroke color must be fully opaque
Error message
The stroke color must be fully opaque
What it means
The GD driver fakes a text stroke by drawing the text repeatedly at pixel offsets in the stroke color beneath the real text, so a semi-transparent stroke would bleed through the glyphs and break the effect. gdStrokeColor() therefore rejects any stroke color whose alpha is below fully opaque (isTransparent() is true for any alpha < 1) with StateException, but only when a stroke effect is active (strokeWidth > 0). Defaults are opaque ('ffffff' stroke, '000000' text), so the error requires an explicitly transparent stroke color; the Imagick driver renders alpha strokes natively and does not throw.
Source
Thrown at src/Drivers/Gd/Modifiers/TextModifier.php:143
->colorProcessor($image)
->export(parent::textColor());
}
/**
* Decode color for stroke (outline) effect in GD compatible format
*
* @throws StateException
*/
protected function gdStrokeColor(ImageInterface $image): int
{
if (!$this->font->hasStrokeEffect()) {
return 0;
}
$color = parent::strokeColor();
if ($color->isTransparent()) {
throw new StateException('The stroke color must be fully opaque');
}
return $this
->driver()
->colorProcessor($image)
->export($color);
}
/**
* Return GD's internal font size
*/
private function gdFont(): int
{
if (!in_array($this->font->size(), range(1, 5))) {
return 1;
}
return (int) $this->font->size();View on GitHub (pinned to 5598b9e397)
Solutions
- Use a fully opaque stroke color: '#ffffff', 'rgb(255, 255, 255)' or an Rgb\Color with alpha 1
- Drop the stroke effect (strokeWidth 0) when transparency is the goal
- Pre-blend the intended color against the known background to get an opaque equivalent
- Switch to the Imagick driver if alpha strokes are a hard requirement
Example fix
// before
$image->text('Draft', 40, 40, fn($font) => $font
->file('arial.ttf')
->stroke('rgba(255,255,255,0.5)', 2));
// after: fully opaque stroke color
$image->text('Draft', 40, 40, fn($font) => $font
->file('arial.ttf')
->stroke('#ffffff', 2)); Defensive patterns
Strategy: validation
Validate before calling
use Intervention\Image\Colors\Rgb\Color as RgbColor;
$stroke = 'rgba(255,255,255,0.5)';
if ($font->strokeWidth() > 0) {
$color = RgbColor::parse($stroke); // hex / rgb() / rgba() / named strings
if ($color->isTransparent()) {
throw new RuntimeException(
'GD requires a fully opaque stroke color; use e.g. #ffffff instead'
);
}
}
$image->text('Draft', 40, 40, $font); Try / catch
use Intervention\Image\Exceptions\StateException;
try {
$image->text('Draft', 40, 40, $font);
} catch (StateException $e) {
// retry with a fully opaque stroke color
$font->setStrokeColor('#ffffff');
$image->text('Draft', 40, 40, $font);
} Prevention
- Keep stroke colors opaque in GD pipelines; alpha belongs to fills, not outlines.
- If alpha strokes are required, switch the pipeline to the Imagick driver.
- Test text effects under every driver you ship.
- Pre-blend rgba outline colors against the known background to get opaque equivalents.
When it happens
Trigger: $image->text(...) with fn($font) => $font->stroke('rgba(255,255,255,0.5)', 2); a stroke color of 'transparent' or any ColorInterface with alpha < 1 while strokeWidth > 0; typography code written against the Imagick driver then run under GD.
Common situations: Design systems specifying rgba() outline colors; theme color tokens with alpha reused for captions and watermarks; driver-agnostic code tested only with Imagick.
Related errors
- Unable to parse RGB color from input "{input}"
- Failed to apply Intervention\Image\Drivers\Gd\Modifiers\Draw
- Failed to normalize background color to RGB color space
- Failed to build watermark image
- The text color must be fully opaque when using the stroke ef
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/2b48a12d018ecf4a.
Report an issue: GitHub.