phacility/phabricator · error · Exception
Unable to imagecreatetruecolor() a new empty image: %s
Error message
Unable to imagecreatetruecolor() a new empty image: %s
What it means
The GD function imagecreatetruecolor($w, $h) returned false after newEmptyImage() had already validated that both dimensions are positive. GD fails this allocation almost exclusively when PHP cannot allocate the w*h truecolor buffer (memory_limit exhausted); the trapped PHP warnings are included in the message. Unlike the nonpositive-dimension error, this means the size was legal but the allocation was refused.
Source
Thrown at src/applications/files/transform/PhabricatorFileImageTransform.php:176
* @param int Desired image width.
* @param int Desired image height.
* @return resource New image resource.
*/
protected function newEmptyImage($w, $h) {
$w = (int)$w;
$h = (int)$h;
if (($w <= 0) || ($h <= 0)) {
throw new Exception(
pht('Can not create an image with nonpositive dimensions.'));
}
$trap = new PhutilErrorTrap();
$img = @imagecreatetruecolor($w, $h);
$errors = $trap->getErrorsAsString();
$trap->destroy();
if ($img === false) {
throw new Exception(
pht(
'Unable to imagecreatetruecolor() a new empty image: %s',
$errors));
}
$trap = new PhutilErrorTrap();
$ok = @imagesavealpha($img, true);
$errors = $trap->getErrorsAsString();
$trap->destroy();
if ($ok === false) {
throw new Exception(
pht(
'Unable to imagesavealpha() a new empty image: %s',
$errors));
}
$trap = new PhutilErrorTrap();
$color = @imagecolorallocatealpha($img, 255, 255, 255, 127);View on GitHub (pinned to 5720a38cfe)
Solutions
- Raise memory_limit for the PHP web and daemon processes (GD needs ~4-5 bytes per pixel per buffer, source and destination).
- Reduce the pixel budget: skip transforms for images near the 4096x4096 cap, or transform to a smaller target size first.
- Wrap transform execution in try/catch and fall back to the original file so a single oversized image does not fail the whole request.
Example fix
// php.ini or php-fpm pool ; before memory_limit = 128M ; after memory_limit = 512M
Defensive patterns
Strategy: fallback
Validate before calling
$needed = $w * $h * 5 * 2; // rough bytes for src+dst buffers
if ($needed > ini_get('memory_limit') converted-to-bytes - memory_get_usage()) {
// skip transform or reduce dimensions
} Try / catch
try {
$transformed = $transform->execute($file);
} catch (Exception $ex) {
$transformed = $file; // allocation failed; degrade to original
} Prevention
- Raise memory_limit on transform-capable hosts; GD needs several bytes per pixel per buffer.
- Bound transform sizes: cap source at 4096x4096 and target dimensions modestly.
- Always provide an original-file fallback when a transform fails.
When it happens
Trigger: Creating a transform canvas for large-but-legal dimensions (e.g. a 4096x4096-max source producing a large intermediate canvas) on a PHP process whose memory_limit is already mostly consumed by the decoded source bitmap.
Common situations: Shared-hosting or container PHP with a low memory_limit; transforms on 16MB files near the size cap where the source bitmap plus destination canvas exceed the limit; other extensions or loaded data leaving little headroom in the request.
Related errors
- Failed to imagecopyresampled() image: %s
- Can not create an image with nonpositive dimensions.
- Unable to imagesavealpha() a new empty image: %s
- Unable to imagecolorallocatealpha() a new empty image: %s
- Unable to imagefill() a new empty image: %s
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/2e9970ffa5da3838.
Report an issue: GitHub.