phacility/phabricator · error · Exception

Unable to load image data with imagecreatefromstring(): %s

Error message

Unable to load image data with imagecreatefromstring(): %s

What it means

imagecreatefromstring() returned false after the earlier pre-flights (getimagesize OK, dimensions positive, pixel count under the cap), meaning GD recognized the container but could not decode the pixel data. Typical causes: the format is compiled out of this GD build (e.g. WebP/AVIF on older GD), the data is truncated/corrupt beyond the header, or decoding exhausted memory. The trapped PHP warnings are included in the message.

Source

Thrown at src/applications/files/transform/PhabricatorFileImageTransform.php:354

    if ($img_pixels > $max_pixels) {
      throw new Exception(
        pht(
          'This image (with dimensions %spx x %spx) is too large to '.
          'transform. The image has %s pixels, but transforms are limited '.
          'to images with %s or fewer pixels.',
          new PhutilNumber($width),
          new PhutilNumber($height),
          new PhutilNumber($img_pixels),
          new PhutilNumber($max_pixels)));
    }

    $trap = new PhutilErrorTrap();
    $image = @imagecreatefromstring($data);
    $errors = $trap->getErrorsAsString();
    $trap->destroy();

    if ($image === false) {
      throw new Exception(
        pht(
          'Unable to load image data with imagecreatefromstring(): %s',
          $errors));
    }

    $this->image = $image;
    return $this->image;
  }

  private function shouldUseImagemagick() {
    if (!PhabricatorEnv::getEnvConfig('files.enable-imagemagick')) {
      return false;
    }

    if ($this->file->getMimeType() != 'image/gif') {
      return false;
    }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Check GD capabilities: php -r 'print_r(gd_info());' — confirm the format (WebP etc.) is enabled; if not, install a PHP/GD build with it and restart php-fpm/phd.
  2. Verify the file decodes locally (GD or an image viewer) and re-upload a non-truncated, mainstream-format copy (JPEG/PNG).
  3. Catch this exception at the transform call and fall back to the original file; optionally restrict 'image' uploads to formats your GD supports.

Example fix

# before: WebP upload, GD without webp support -> transform throws
# after: confirm support, else reject/skip
php -r 'var_dump(gd_info()["WebP Support"]);'
# false => install php-gd with webp (e.g. newer distro package), restart php-fpm + phd
Defensive patterns

Strategy: try-catch

Validate before calling

$info = @getimagesize($file->getURI());
$known_good = array(IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF);
if ($info === false || !in_array($info[2], $known_good, true)) {
  return $file; // format this GD build may not decode; skip transform
}

Type guard

function gdCanDecodeFormat(int $imagetype): bool {
  $gd = gd_info();
  switch ($imagetype) {
    case IMAGETYPE_WEBP: return !empty($gd['WebP Support']);
    case IMAGETYPE_JPEG: return !empty($gd['JPEG Support']);
    case IMAGETYPE_PNG: return !empty($gd['PNG Support']);
    case IMAGETYPE_GIF: return !empty($gd['GIF Support']);
    default: return false;
  }
}

Try / catch

try {
  $transformed = $file->applyTransform($xform);
} catch (Exception $ex) {
  phlog($ex);
  $transformed = $file; // decode failed; serve original
}

Prevention

When it happens

Trigger: Transforming an image whose header parses but whose body GD cannot decode — WebP on a GD without WebP support, AVIF/XL formats GD never had, files truncated mid-transfer, or progressive/animated variants a particular GD mishandles.

Common situations: PHP built with limited GD format support (common on minimal/container images); browsers happily producing WebP/AVIF uploads while the server GD predates them; interrupted uploads that keep a valid header but lose the tail.

Related errors


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