PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Reader\Exception
Unable to identify a reader for this file
Error message
Unable to identify a reader for this file
What it means
IOFactory::load()/identify() first guesses a reader from the file extension, then falls back to trying canRead() on every registered reader. If the guessed reader rejects the file and so does every other one, this exception is thrown: the file is not recognizable as any supported spreadsheet format. It is a content-signature failure, not a permissions error.
Source
Thrown at src/PhpSpreadsheet/IOFactory.php:218
// Let's see if we are lucky
if ($reader->canRead($filename)) {
return $reader;
}
}
// If we reach here then "lucky guess" didn't give any result
// Try walking through all the options in self::$readers (or the selected subset)
foreach ($testReaders as $readerType => $class) {
// Ignore our original guess, we know that won't work
if ($readerType !== $guessedReader) {
$reader = self::createReader($readerType, $testReaders);
if ($reader->canRead($filename)) {
return $reader;
}
}
}
throw new Reader\Exception('Unable to identify a reader for this file');
}
/**
* Guess a reader type from the file extension, if any.
*/
private static function getReaderTypeFromExtension(string $filename): ?string
{
$pathinfo = pathinfo($filename);
if (!isset($pathinfo['extension'])) {
return null;
}
return match (strtolower($pathinfo['extension'])) {
// Excel (OfficeOpenXML) Spreadsheet
'xlsx',
// Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded)
'xlsm',
// Excel (OfficeOpenXML) TemplateView on GitHub (pinned to 65b080eef4)
Solutions
- Open with the concrete reader you expect (e.g. new Reader\Xlsx()) to get a clearer error
- Verify the file signature first: ZIP 'PK' header for .xlsx, OLE header for .xls
- Reject password-protected workbooks early with a clear user-facing message
- Validate uploads by content type, not just extension
Example fix
// before
$spreadsheet = IOFactory::load($uploadedPath);
// after
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
if (!$reader->canRead($uploadedPath)) {
throw new InvalidArgumentException('Not a readable XLSX file');
}
$spreadsheet = $reader->load($uploadedPath); Defensive patterns
Strategy: validation
Validate before calling
/** Cheap signature check before IOFactory::load(). */
function looksLikeSpreadsheet(string $path): bool
{
$fh = fopen($path, 'rb');
if ($fh === false) {
return false;
}
$head = (string) fread($fh, 8);
fclose($fh);
return str_starts_with($head, 'PK') // zip: xlsx/ods
|| str_starts_with($head, "\xd0\xcf\x11\xe0") // OLE: legacy xls
|| trim($head) === '' // possible csv/sylk
|| stripos($head, '<') !== false; // html/xml-ish
}
if (!looksLikeSpreadsheet($uploadedPath)) {
throw new InvalidArgumentException('Uploaded file is not a spreadsheet');
}
$spreadsheet = IOFactory::load($uploadedPath); Try / catch
try {
$spreadsheet = IOFactory::load($uploadedPath);
} catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
if (str_contains($e->getMessage(), 'Unable to identify a reader')) {
// user-facing error: the file is not a supported spreadsheet (or is encrypted)
throw new UploadRejectException('Unsupported or corrupted file. Please upload XLSX, XLS, ODS or CSV.', 0, $e);
}
throw $e;
} Prevention
- Validate upload magic bytes (PK for zip-based formats) before handing files to IOFactory
- Reject password-protected workbooks early - PhpSpreadsheet cannot decrypt them
- For known formats, use the concrete reader directly for clearer failures
When it happens
Trigger: IOFactory::load('report.xyz') with an unrecognized format; a password-protected/encrypted .xlsx (canRead fails); an HTML error page or empty file named .xlsx; a truncated upload.
Common situations: User uploads with spoofed or missing extensions; encrypted workbooks (PhpSpreadsheet cannot decrypt); API responses saved as .xlsx that are actually JSON/HTML; CSVs with unusual encodings failing the Csv canRead heuristic.
Related errors
- No reader found for type $readerType
- Registered readers must implement PhpOffice\PhpSpreadsheet\R
- Cannot load invalid XML ${fileOrString}: ${filename}
- Cannot load invalid XML $fileOrString: $filename
- File doesn't seem to be an OLE container.
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/4ad04f206df88273.
Report an issue: GitHub.