PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
dggContainer is unexpectedly null
Error message
dggContainer is unexpectedly null
What it means
Shared\Escher models the binary Escher drawing structures of .xls files; getDggContainerOrThrow() returns the drawing-group container or throws when it was never set (src/PhpSpreadsheet/Shared/Escher.php:32). The Xls reader dereferences it when reading workbook-level images: getDggContainerOrThrow()->getBstoreContainerOrThrow() in src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php:500, so the throw means the Escher stream lacked the Dgg container.
Source
Thrown at src/PhpSpreadsheet/Shared/Escher.php:32
/**
* Drawing Container.
*/
private ?Escher\DgContainer $dgContainer = null;
/**
* Get Drawing Group Container.
*/
public function getDggContainer(): ?Escher\DggContainer
{
return $this->dggContainer;
}
/**
* Get Drawing Group Container.
*/
public function getDggContainerOrThrow(): Escher\DggContainer
{
return $this->dggContainer ?? throw new SpreadsheetException('dggContainer is unexpectedly null');
}
/**
* Set Drawing Group Container.
*/
public function setDggContainer(Escher\DggContainer $dggContainer): Escher\DggContainer
{
return $this->dggContainer = $dggContainer;
}
/**
* Get Drawing Container.
*/
public function getDgContainer(): ?Escher\DgContainer
{
return $this->dgContainer;
}
View on GitHub (pinned to 65b080eef4)
Solutions
- Re-save the workbook in Excel or LibreOffice (open + save) to rebuild a complete Escher structure, or convert to .xlsx
- Strip drawings before processing if images are irrelevant: convert to CSV/xlsx without images
- Catch the exception around load and quarantine/reject the specific file in batch pipelines
- Update PhpSpreadsheet — these OrThrow accessors replaced silent null handling, and reader robustness improves across releases
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check file integrity before the reader dereferences Escher containers
$zipCheck = true; // OLE2 files: verify size > 0 and signature
$fh = fopen($path, 'rb');
$sig = fread($fh, 8);
fclose($fh);
if ($sig !== "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1") {
$zipCheck = false;
}
if (!$zipCheck) {
throw new InvalidArgumentException('Not a valid .xls workbook');
} Try / catch
try {
$spreadsheet = $reader->load($path);
} catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
if (str_contains($e->getMessage(), 'dggContainer')) {
// malformed Escher drawing group: route to repair/re-save pipeline
}
} Prevention
- Re-save legacy drawing-heavy .xls files via LibreOffice at ingest
- Quarantine files whose Escher structures are incomplete instead of retrying
- Keep the library updated for reader hardening
When it happens
Trigger: Reading an .xls with drawings where the workbook-level Escher record set is truncated or omits the drawing-group container — typically files emitted by legacy exporters (SAP, old reporting tools) or corrupted downloads — while sheet-level records still advertise images.
Common situations: Enterprise report archives processed in batch; files that survived partial transfers; workbooks from non-Excel writers with incomplete Escher implementations.
Related errors
- dgContainer is unexpectedly null
- spgrContainer is unexpectedly null
- bstoreContainer is unexpectedly null
- Unknown codepage: $codePage
- $bitmap doesn't contain enough data.\n
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/2d5ca8b4ddf8ea32.
Report an issue: GitHub.