PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
dgContainer is unexpectedly null
Error message
dgContainer is unexpectedly null
What it means
getDgContainerOrThrow() on Shared\Escher returns the per-sheet drawing container or throws when unset (src/PhpSpreadsheet/Shared/Escher.php:56). The Xls reader calls it unconditionally while reading worksheet drawings — $escherWorksheet->getDgContainerOrThrow()->getSpgrContainerOrThrow() at src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php:440 — so an Escher stream for a sheet without a valid Dg container triggers it.
Source
Thrown at src/PhpSpreadsheet/Shared/Escher.php:56
public function setDggContainer(Escher\DggContainer $dggContainer): Escher\DggContainer
{
return $this->dggContainer = $dggContainer;
}
/**
* Get Drawing Container.
*/
public function getDgContainer(): ?Escher\DgContainer
{
return $this->dgContainer;
}
/**
* Get Drawing Container.
*/
public function getDgContainerOrThrow(): Escher\DgContainer
{
return $this->dgContainer ?? throw new SpreadsheetException('dgContainer is unexpectedly null');
}
/**
* Set Drawing Container.
*/
public function setDgContainer(Escher\DgContainer $dgContainer): Escher\DgContainer
{
return $this->dgContainer = $dgContainer;
}
}
View on GitHub (pinned to 65b080eef4)
Solutions
- Re-save via Excel/LibreOffice to normalize drawing structures, or convert to .xlsx
- If drawings are not needed, convert to CSV or strip images before processing
- Catch and quarantine the file in automated pipelines; report the file as malformed
- Update PhpSpreadsheet to pick up reader robustness fixes
Defensive patterns
Strategy: try-catch
Validate before calling
// Cheap gate: skip the Xls reader entirely for non-OLE2 uploads (see error 187 helper)
if (!looksLikeOle2Spreadsheet($path)) {
return reject('Corrupt .xls');
} Try / catch
try {
$spreadsheet = $reader->load($path);
} catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
if (str_contains($e->getMessage(), 'dgContainer')) {
repairPipeline($path); // Excel/LibreOffice re-save, then retry once
}
} Prevention
- Normalize third-party .xls output through a re-save step
- Log the sheet index that failed to correlate with corrupt drawings
- Prefer .xlsx ingest formats where the pipeline allows
When it happens
Trigger: Reading an .xls whose sheet-level Escher data is malformed or missing the Dg container while the surrounding records still indicate drawings exist (LoadSpreadsheet.php:440 dereferences both OrThrow accessors in one chain).
Common situations: Legacy third-party .xls generators with incomplete Escher output; corrupted drawing records after bad transfers; files edited by multiple old tools.
Related errors
- dggContainer 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/7d176660dabe909e.
Report an issue: GitHub.