PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
Could not clone image resource
Error message
Could not clone image resource
What it means
MemoryDrawing holds a live GD image resource. When it is cloned — directly, or indirectly via clone $worksheet, Worksheet::copy(), or copying a whole spreadsheet — cloneResource() rebuilds the canvas with imagecreatetruecolor() for truecolor images. If GD returns false (zero width/height from a broken source, or memory exhausted allocating a large bitmap) it throws 'Could not clone image resource'.
Source
Thrown at src/PhpSpreadsheet/Worksheet/MemoryDrawing.php:89
public function __clone()
{
parent::__clone();
$this->cloneResource();
}
private function cloneResource(): void
{
if (!$this->imageResource) {
return;
}
$width = (int) imagesx($this->imageResource);
$height = (int) imagesy($this->imageResource);
if (imageistruecolor($this->imageResource)) {
$clone = imagecreatetruecolor($width, $height);
if (!$clone) {
throw new Exception('Could not clone image resource');
}
imagealphablending($clone, false);
imagesavealpha($clone, true);
} else {
$clone = imagecreate($width, $height);
if (!$clone) {
throw new Exception('Could not clone image resource');
}
// If the image has transparency...
$transparent = imagecolortransparent($this->imageResource);
if ($transparent >= 0) {
// Starting with Php8.0, next function throws rather than return false
$rgb = imagecolorsforindex($this->imageResource, $transparent);
imagesavealpha($clone, true);
$color = imagecolorallocatealpha($clone, $rgb['red'], $rgb['green'], $rgb['blue'], $rgb['alpha']);View on GitHub (pinned to 65b080eef4)
Solutions
- Raise PHP memory_limit to cover roughly width*height*8 bytes for the largest drawing.
- Avoid cloning the drawing: rebuild it from its rendered bytes with MemoryDrawing::fromString($drawing->getContents()).
- Validate sources (getimagesize / non-zero imagesx-imagesy) before they become MemoryDrawings so clones never see 0-size resources.
Example fix
// before $newSheet = clone $sheet; // contains a MemoryDrawing -> Could not clone image resource // after $bytes = $drawing->getContents(); $drawing2 = MemoryDrawing::fromString($bytes); // fresh resource, no GD clone
Defensive patterns
Strategy: try-catch
Validate before calling
$gd = $memoryDrawing->getImageResource();
if ($gd === null || imagesx($gd) < 1 || imagesy($gd) < 1) {
$memoryDrawing = MemoryDrawing::fromString($memoryDrawing->getContents()); // rebuild a valid resource
}
// cloning now has non-zero dimensions to work with Try / catch
try {
$copy = clone $worksheet; // or $sheet->copy()
} catch (PhpSpreadsheetException $e) {
// GD could not allocate the clone canvas: free memory or rebuild the drawing
$bytes = $memoryDrawing->getContents();
// re-attach as MemoryDrawing::fromString($bytes), then retry the copy
} Prevention
- Cloning doubles each bitmap — budget roughly width*height*8 bytes and check memory_limit
- Never build a MemoryDrawing from undecodable or zero-size sources
- Prefer rebuilding drawings from rendered bytes over deep-cloning whole sheets
When it happens
Trigger: clone $worksheet containing a MemoryDrawing; template flows calling $sheet->copy() once per data set; a GD resource whose width or height is 0 because the image partially decoded; a 6000x6000 truecolor canvas exceeding memory_limit during allocation.
Common situations: Report generators duplicating a styled template sheet; memory_limit pressure because cloning doubles each bitmap (~4 bytes/pixel twice); MemoryDrawing objects built from truncated strings.
Related errors
- Could not get image alpha color
- Value cannot be converted to an image
- Unsupported binary comparison operator
- Cloning the calculation engine is not allowed!
- Unsupported numeric binary operation
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/05768c3c1ff802e9.
Report an issue: GitHub.