{"record":{"id":"1c82b94ba94323d9","repo":"PHPOffice/PhpSpreadsheet","slug":"filename-is-an-invalid-spreadsheet-file-1c82b9","errorCode":null,"errorMessage":"${filename} is an Invalid Spreadsheet file.","messagePattern":"(.+?) is an Invalid Spreadsheet file\\.","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Reader\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Reader/Xml.php","lineNumber":161,"sourceCode":"            }\n        } catch (Throwable $e) {\n            throw new Exception($this->xmlFailMessage, 0, $e);\n        }\n        $this->fileContents = '';\n\n        return $xml;\n    }\n\n    /**\n     * Reads names of the worksheets from a file, without parsing the whole file to a Spreadsheet object.\n     *\n     * @return string[]\n     */\n    public function listWorksheetNames(string $filename): array\n    {\n        File::assertFile($filename);\n        if (!$this->canRead($filename)) {\n            throw new Exception($filename . ' is an Invalid Spreadsheet file.');\n        }\n\n        $worksheetNames = [];\n\n        $xml = $this->trySimpleXMLLoadStringPrivate($filename);\n        if ($xml === false) {\n            throw new Exception(\"Problem reading {$filename}\");\n        }\n\n        $xml_ss = $xml->children(self::NAMESPACES_SS);\n        foreach ($xml_ss->Worksheet as $worksheet) {\n            $worksheet_ss = self::getAttributes($worksheet, self::NAMESPACES_SS);\n            $worksheetNames[] = (string) $worksheet_ss['Name'];\n        }\n\n        return $worksheetNames;\n    }\n","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Reader/Xml.php#L143-L179","documentation":"listWorksheetNames() first calls canRead(), which requires the file to contain both the '<?xml version=\"1.0\"' declaration and the xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\" namespace. If either signature substring is missing, the file is treated as not being an Excel 2003 SpreadsheetML file.","triggerScenarios":"Calling listWorksheetNames() with a binary .xls, a zipped .xlsx, plain XML without the Office namespace, or an HTML file saved with an .xml extension.","commonSituations":"Import pipelines that assume every upload is SpreadsheetML; users renaming files to fake the extension; XML exports from systems that use a different schema.","solutions":["Use IOFactory::identify($filename) first and dispatch to the matching reader instead of hardcoding Reader\\Xml","Call $reader->canRead($filename) yourself and return a friendly 'unsupported format' message when false","If the file is real Excel, convert it to SpreadsheetML/xlsx or use the appropriate reader (Xls/Xlsx)"],"exampleFix":"// before\n$names = (new \\PhpOffice\\PhpSpreadsheet\\Reader\\Xml())->listWorksheetNames('book.xlsx'); // Invalid Spreadsheet file\n\n// after\n$type = \\PhpOffice\\PhpSpreadsheet\\IOFactory::identify('book.xlsx');\n$names = \\PhpOffice\\PhpSpreadsheet\\IOFactory::createReader($type)->listWorksheetNames('book.xlsx');","handlingStrategy":"validation","validationCode":"$reader = new \\PhpOffice\\PhpSpreadsheet\\Reader\\Xml();\nif (!$reader->canRead($path)) {\n    throw new InvalidArgumentException('Not an Excel 2003 SpreadsheetML file');\n}\n$names = $reader->listWorksheetNames($path);","typeGuard":"function isSpreadsheetMl(string $path): bool\n{\n    return (new \\PhpOffice\\PhpSpreadsheet\\Reader\\Xml())->canRead($path);\n}","tryCatchPattern":null,"preventionTips":["Dispatch on IOFactory::identify() rather than assuming the XML format","Gate upload handling with canRead() to fail with a clear message","Accept .xlsx by default; treat SpreadsheetML as a legacy convenience"],"tags":["xml","spreadsheetml","format-detection","phpspreadsheet"],"backgroundTag":"wrong-file-format","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}