PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
bstoreContainer is unexpectedly null
Error message
bstoreContainer is unexpectedly null
What it means
DggContainer::getBstoreContainerOrThrow() returns the BLIP store (embedded image storage) of the workbook-level Escher or throws when unset (src/PhpSpreadsheet/Shared/Escher/DggContainer.php:104). The Xls reader chains it — getDggContainerOrThrow()->getBstoreContainerOrThrow() — at src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php:500 when resolving images referenced by sheet drawings.
Source
Thrown at src/PhpSpreadsheet/Shared/Escher/DggContainer.php:104
public function setCSpSaved(int $value): void
{
$this->cSpSaved = $value;
}
/**
* Get BLIP Store Container.
*/
public function getBstoreContainer(): ?DggContainer\BstoreContainer
{
return $this->bstoreContainer;
}
/**
* Get BLIP Store Container.
*/
public function getBstoreContainerOrThrow(): DggContainer\BstoreContainer
{
return $this->bstoreContainer ?? throw new SpreadsheetException('bstoreContainer is unexpectedly null');
}
/**
* Set BLIP Store Container.
*/
public function setBstoreContainer(DggContainer\BstoreContainer $bstoreContainer): void
{
$this->bstoreContainer = $bstoreContainer;
}
/**
* Set an option for the drawing group.
*
* @param int $property The number specifies the option
*/
public function setOPT(int $property, mixed $value): void
{
$this->OPT[$property] = $value;View on GitHub (pinned to 65b080eef4)
Solutions
- Re-save the workbook in Excel/LibreOffice (which rebuilds consistent Escher) or convert to .xlsx
- If images are unnecessary, convert to CSV or a drawing-free format before processing
- Catch the exception in batch readers and quarantine the file
- Update PhpSpreadsheet to benefit from reader hardening
Defensive patterns
Strategy: try-catch
Validate before calling
// If images are not required, read without them to sidestep Bstore dereference $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls(); $reader->setReadDataOnly(true); // skips drawing/image processing $spreadsheet = $reader->load($path);
Try / catch
try {
$spreadsheet = (new \PhpOffice\PhpSpreadsheet\Reader\Xls())->load($path);
} catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
if (str_contains($e->getMessage(), 'bstoreContainer')) {
$spreadsheet = (new \PhpOffice\PhpSpreadsheet\Reader\Xls())
->setReadDataOnly(true)
->load($path);
}
} Prevention
- Use setReadDataOnly(true) when images are irrelevant
- Re-save inconsistent workbooks before automated processing
- Quarantine files whose images fail to resolve rather than retrying
When it happens
Trigger: Reading an .xls where sheet-level Escher references images but the workbook-level Dgg container has no Bstore container (images referenced yet never stored) — inconsistent Escher produced by broken writers or corruption.
Common situations: Legacy .xls files from non-Excel tools that emit image references without the store; files processed by tools that dropped OLE streams; archived reports.
Related errors
- dggContainer is unexpectedly null
- dgContainer is unexpectedly null
- spgrContainer 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/3dd8320200637a60.
Report an issue: GitHub.