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

  1. Raise memory_limit for the PHP web and daemon processes (GD needs ~4-5 bytes per pixel per buffer, source and destination).
  2. Reduce the pixel budget: skip transforms for images near the 4096x4096 cap, or transform to a smaller target size first.
  3. 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

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


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/2e9970ffa5da3838. Report an issue: GitHub.