{"record":{"id":"a1f55be4650d6015","repo":"PHPOffice/PhpSpreadsheet","slug":"cannot-load-invalid-xml-fileorstring-filename","errorCode":null,"errorMessage":"Cannot load invalid XML $fileOrString: $filename","messagePattern":"Cannot load invalid XML \\$fileOrString: \\$filename","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Reader\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Reader/Xml.php","lineNumber":297,"sourceCode":"     *\n     * @param string $filename file name if useContents is false else file contents\n     */\n    public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet, bool $useContents = false): Spreadsheet\n    {\n        if ($useContents) {\n            $this->fileContents = $filename;\n            $fileOrString = 'string';\n        } else {\n            File::assertFile($filename);\n            if (!$this->canRead($filename)) {\n                throw new Exception($filename . ' is an Invalid Spreadsheet file.');\n            }\n            $fileOrString = 'file';\n        }\n\n        $xml = $this->trySimpleXMLLoadStringPrivate($filename, $fileOrString);\n        if ($xml === false) {\n            throw new Exception($this->xmlFailMessage);\n        }\n\n        $namespaces = $xml->getNamespaces(true);\n\n        (new Properties($spreadsheet))->readProperties($xml, $namespaces);\n\n        $this->styles = (new Style())->parseStyles($xml, $namespaces);\n        if (isset($this->styles['Default']) && is_array($this->styles['Default'])) {\n            $spreadsheet->getCellXfCollection()[0]->applyFromArray($this->styles['Default']);\n        }\n\n        $worksheetID = 0;\n        $xml_ss = $xml->children(self::NAMESPACES_SS);\n\n        $sheetCreated = false;\n        /** @var null|SimpleXMLElement $worksheetx */\n        foreach ($xml_ss->Worksheet as $worksheetx) {\n            $worksheet = $worksheetx ?? new SimpleXMLElement('<xml></xml>');","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Reader/Xml.php#L279-L315","documentation":"Thrown by the SpreadsheetML (Excel 2003 XML) reader when simplexml cannot parse the input; the message records whether the input was a file or a string ('Cannot load invalid XML file: ...' / '... string: ...', set in trySimpleXMLLoadStringPrivate at src/PhpSpreadsheet/Reader/Xml.php:122). It means the content is either not XML at all or violates XML well-formedness. For file input it only fires after File::assertFile() and the reader's canRead() signature check already passed; for string input no canRead check is performed, so any malformed string fails here.","triggerScenarios":"Calling Reader\\Xml::loadSpreadsheetFromString() with a truncated or non-XML string (the string branch in loadSpreadsheetFromFile/FromString sets fileOrString='string' and skips canRead); loading a file that passes canRead() but contains unclosed tags or an invalid encoding declaration; passing an HTML error page fetched over HTTP as the spreadsheet string.","commonSituations":"Wrong reader forced for the actual format (an .xlsx renamed to .xml); truncated downloads; BOM-prefixed or entity-laden markup; strings built by concatenation that lose closing tags; CSV content fed to the XML reader.","solutions":["Confirm the input is really SpreadsheetML and well-formed: run xmllint --noout file.xml or simplexml_load_string() on it before loading","Let PhpSpreadsheet choose the reader: IOFactory::identify()/IOFactory::load() instead of instantiating Reader\\Xml directly","If loading from a string, validate with simplexml_load_string() first and handle false before calling the reader","Re-export the source file as 'Excel 2003 XML' from Excel/LibreOffice to regenerate valid markup"],"exampleFix":"// before\n$reader = new \\PhpOffice\\PhpSpreadsheet\\Reader\\Xml();\n$spreadsheet = $reader->load('export.xml'); // throws on malformed markup\n\n// after\n$type = \\PhpOffice\\PhpSpreadsheet\\IOFactory::identify('export.xml');\n$spreadsheet = \\PhpOffice\\PhpSpreadsheet\\IOFactory::createReaderForFile('export.xml')->load('export.xml');","handlingStrategy":"try-catch","validationCode":"use PhpOffice\\PhpSpreadsheet\\Reader\\Xml;\n\n$isReadable = (new Xml())->canRead($path); // cheap signature check\n$xmlOk = $isReadable && simplexml_load_string(file_get_contents($path)) !== false;","typeGuard":"function isParsableXml(string $content): bool\n{\n    return simplexml_load_string($content) !== false;\n}","tryCatchPattern":"try {\n    $spreadsheet = $reader->load($path);\n} catch (\\PhpOffice\\PhpSpreadsheet\\Reader\\Exception $e) {\n    // covers both 'Cannot load invalid XML file: ...' and assertFile failures\n    logger()->warning('Rejected malformed spreadsheet', ['file' => $path, 'err' => $e->getMessage()]);\n    return null;\n}","preventionTips":["Let IOFactory::identify() pick the reader instead of hardcoding Reader\\Xml","xmllint or simplexml-validate input from untrusted sources before loading","Keep the reader's canRead() in upload validation flows","For string loads, validate with simplexml_load_string() first"],"tags":["xml","reader","file-format","parsing"],"backgroundTag":"malformed-xml-rejected","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}