PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Reader\Exception
Could not find zip member $zipfile
Error message
Could not find zip member $zipfile
What it means
The second stage of File::assertFile() when a $zipMember is supplied (src/PhpSpreadsheet/Shared/File.php:174): it probes zip://$filename#$zipMember, retries with backslashes (workbooks saved by some Windows tools store members with '\' separators), and throws when both fail. Readers use it to fetch specific archive parts of an .xlsx (e.g. xl/worksheets/sheet1.xml, drawings, sharedStrings referenced by rels).
Source
Thrown at src/PhpSpreadsheet/Shared/File.php:174
}
/**
* Assert that given path is an existing file and is readable, otherwise throw exception.
*/
public static function assertFile(string $filename, string $zipMember = ''): void
{
self::prohibitWrappers($filename);
if (!is_file($filename) || !is_readable($filename)) {
throw new ReaderException('File "' . $filename . '" does not exist or is not readable.');
}
if ($zipMember !== '') {
$zipfile = "zip://$filename#$zipMember";
if (!self::fileExists($zipfile)) {
// Has the file been saved with Windoze directory separators rather than unix?
$zipfile = "zip://$filename#" . str_replace('/', '\\', $zipMember);
if (!self::fileExists($zipfile)) {
throw new ReaderException("Could not find zip member $zipfile");
}
}
}
}
/**
* Same as assertFile, except return true/false and don't throw Exception.
* Will nevertheless throw if filename uses invalid protocol, e.g. phar.
*/
public static function testFileNoThrow(string $filename, ?string $zipMember = null): bool
{
self::prohibitWrappers($filename);
if (!is_file($filename) || !is_readable($filename)) {
return false;
}
if ($zipMember === null) {
return true;
}View on GitHub (pinned to 65b080eef4)
Solutions
- Open the archive yourself and inspect actual member names: $zip = new ZipArchive(); $zip->open($file); then list entries to spot missing or oddly-cased parts
- Re-save the workbook in Excel/LibreOffice to rebuild a normalized archive, or regenerate from the source system
- Catch the ReaderException in upload handlers and quarantine the file with a user-friendly message
- Validate zip integrity (unzip -t) at the trust boundary before processing
Example fix
// before
$spreadsheet = (new \PhpOffice\PhpSpreadsheet\Reader\Xlsx())->load('report.xlsx'); // throws on missing member
// after
$zip = new \ZipArchive();
if ($zip->open('report.xlsx') !== true
|| $zip->locateName('xl/worksheets/sheet1.xml') === false) {
throw new \InvalidArgumentException('Workbook is missing required parts.');
}
$zip->close();
$spreadsheet = (new \PhpOffice\PhpSpreadsheet\Reader\Xlsx())->load('report.xlsx'); Defensive patterns
Strategy: validation
Validate before calling
function xlsxHasEssentialMembers(string $path): bool
{
$zip = new \ZipArchive();
if ($zip->open($path) !== true) { return false; }
$ok = $zip->locateName('[Content_Types].xml') !== false
&& $zip->locateName('xl/workbook.xml') !== false;
$zip->close();
return $ok;
}
if (!xlsxHasEssentialMembers($path)) {
throw new \InvalidArgumentException('Incomplete .xlsx archive');
} Try / catch
try {
$spreadsheet = $reader->load($path);
} catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
if (str_contains($e->getMessage(), 'Could not find zip member')) {
quarantine($path, $e->getMessage()); // missing part: repair via re-save or reject
}
} Prevention
- unzip -t or ZipArchive integrity checks at the upload boundary
- Re-save third-party-generated workbooks with Excel/LibreOffice before processing
- Quarantine (not retry) archives with missing referenced parts
When it happens
Trigger: An .xlsx missing a part its relationships reference (sheet XML, drawing, sharedStrings); members stored with unexpected path casing or nesting; a corrupt zip central directory so member lookup fails despite the file opening.
Common situations: Third-party xlsx generators (report SDKs, Java/Python tools) that omit referenced-but-optional parts; partially uploaded files; archives rewritten by tools that changed internal paths; e-mail/AV-mangled files.
Related errors
- Unable to read data from {$pFilename}
- File $filename does not exist
- Unknown codepage: $codePage
- dggContainer is unexpectedly null
- dgContainer is unexpectedly null
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/b344057dfb7d35b3.
Report an issue: GitHub.