Intervention/image · error · ModifierException
Failed to apply Intervention\Image\Drivers\Gd\Modifiers\Trim
Error message
Failed to apply Intervention\Image\Drivers\Gd\Modifiers\TrimModifier, unable to create canvas
What it means
The GD trim() modifier first copies the source image onto a fresh truecolor canvas (transparencySafeVersion) so imagecropauto() cannot destroy alpha information. That copy is created with imagecreatetruecolor($width, $height), and it returned false, meaning GD could not allocate the canvas. In practice this is almost always PHP's memory_limit: a truecolor canvas costs roughly width x height x 5 bytes on top of the memory already held by the source image.
Source
Thrown at src/Drivers/Gd/Modifiers/TrimModifier.php:75
* Copy the given GdImage to a fresh true color canvas that has no transparent color set.
*
* imagecropauto() internally drops every pixel that matches the image's "transparent
* color". palette images that were converted to true color while decoding carry over
* a bogus transparent color, which would turn all transparent areas opaque during the
* crop. transfer the image to a fresh true color canvas without a transparent color
* to preserve the alpha channel.
*
* @throws ModifierException
*/
private function transparencySafeVersion(GdImage $gd): GdImage
{
$width = imagesx($gd);
$height = imagesy($gd);
$canvas = imagecreatetruecolor($width, $height);
if ($canvas === false) {
throw new ModifierException(
'Failed to apply ' . self::class . ', unable to create canvas',
);
}
imagealphablending($canvas, false);
imagesavealpha($canvas, true);
// pre-fill with the original transparent color (if any).
$transparent = imagecolortransparent($gd);
if ($transparent !== -1) {
imagefill($canvas, 0, 0, $transparent);
}
// copy resolution to canvas
$resolution = imageresolution($gd);
if (is_array($resolution) && array_key_exists(0, $resolution) && array_key_exists(1, $resolution)) {
imageresolution($canvas, $resolution[0], $resolution[1]);
}View on GitHub (pinned to 5598b9e397)
Solutions
- Raise the memory budget for the image worker: ini_set('memory_limit', '512M'); or set memory_limit in php.ini / the PHP-FPM pool.
- Budget the GD cost up front (about width*height*5 bytes for the trim canvas on top of the source) and reject or downscale oversized inputs with scaleDown() before trim().
- Switch the ImageManager to the Imagick driver, which does not allocate a monolithic PHP-memory canvas for trimming.
- Move trimming into a dedicated queue job so the operation is not bound by the web request's memory_limit.
Example fix
// before
$image = ImageManager::gd()->read('poster.tif')->trim();
// after: GD trim() duplicates the image onto a new truecolor canvas (~5 bytes/pixel)
ini_set('memory_limit', '1G');
$image = ImageManager::gd()->read('poster.tif')->trim(); Defensive patterns
Strategy: validation
Validate before calling
// GD trim() duplicates the image onto a new truecolor canvas (~5 bytes/pixel)
$bytesNeeded = $image->width() * $image->height() * 5;
$bytesFree = return_bytes(ini_get('memory_limit')) - memory_get_usage();
if ($bytesNeeded > $bytesFree) {
$image = $image->scaleDown(width: 4000); // or reject with a clear message
}
$image->trim(); Try / catch
try { $image->trim(); } catch (ModifierException $e) { error_log(...); $image = $image->scaleDown(width: 4000)->trim(); } Prevention
- Track width*height of accepted uploads and reject or downscale images whose pixel budget your memory_limit cannot hold twice.
- Run image work in dedicated queue workers with a raised memory_limit instead of web requests.
- Prefer the Imagick driver for very large sources.
When it happens
Trigger: Calling trim() on the GD driver for a large image (a 6000x4000 photo needs ~120 MB just for the duplicate canvas) while memory_limit is 128M/256M; pipelines that keep several GdImage buffers alive (resize + trim + watermark) so the extra canvas pushes the request over the limit.
Common situations: Phone or camera originals (12-50 MP) trimmed on shared hosting with default memory_limit; long-running queue workers whose memory accumulates over many images; high-DPI scans.
Related errors
- Failed to create new image
- Failed to create new image while cloning
- Trim modifier cannot be applied to animated images
- Failed to apply Intervention\Image\Drivers\Gd\Modifiers\Trim
- Failed to apply Intervention\Image\Drivers\Gd\Modifiers\Trim
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/58e012f9808fe5b8.
Report an issue: GitHub.