{"record":{"id":"67fd23394f68f448","repo":"sebastianbergmann/phpunit","slug":"could-not-read-xml-from-file-s","errorCode":null,"errorMessage":"Could not read XML from file \"%s\"","messagePattern":"Could not read XML from file \"(.+?)\"","errorType":"exception","errorClass":"PHPUnit\\Util\\Xml\\XmlException","httpStatus":null,"severity":"error","filePath":"src/Util/Xml/Loader.php","lineNumber":42,"sourceCode":"/**\n * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit\n *\n * @internal This class is not covered by the backward compatibility promise for PHPUnit\n */\nfinal readonly class Loader\n{\n    /**\n     * @throws XmlException\n     */\n    public function loadFile(string $filename, bool $ignoreComments = false): DOMDocument\n    {\n        $reporting = error_reporting(0);\n        $contents  = file_get_contents($filename);\n\n        error_reporting($reporting);\n\n        if ($contents === false) {\n            throw new XmlException(\n                sprintf(\n                    'Could not read XML from file \"%s\"',\n                    $filename,\n                ),\n            );\n        }\n\n        if (trim($contents) === '') {\n            throw new XmlException(\n                sprintf(\n                    'Could not parse XML from empty file \"%s\"',\n                    $filename,\n                ),\n            );\n        }\n\n        return $this->load($contents, $ignoreComments);\n    }","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Util/Xml/Loader.php#L24-L60","documentation":"Xml\\Loader::loadFile() reads a file with error-suppressed file_get_contents() before parsing; when the read fails it throws XmlException('Could not read XML from file \"<path>\"'). PHPUnit uses this loader for phpunit.xml itself, --configuration targets, baseline files, and migration — so the error usually means the configuration file named on the command line cannot be read.","triggerScenarios":"Running `vendor/bin/phpunit --configuration path/to/phpunit.xml` (or when PHPUnit auto-loads a config) where the file does not exist at that path, is not readable by the current user, or is outside the open_basedir allow-list. Also triggered programmatically via Loader::loadFile() on any missing file.","commonSituations":"Wrong relative path because PHPUnit was started from a different working directory; config paths broken in CI after directory restructure; permission changes when the CI user changed; open_basedir restrictions on shared hosting.","solutions":["Check the path resolves from the directory you invoke PHPUnit in: `test -r path/to/phpunit.xml`","Use an absolute path for --configuration, or cd into the project root so auto-discovery finds phpunit.xml","Fix file permissions if the runner user cannot read it (chown/chmod)","Remove open_basedir restrictions for the config location or move the file inside the allowed paths"],"exampleFix":"# before\n$ cd /tmp && vendor/bin/phpunit --configuration phpunit.xml\n# XmlException: Could not read XML from file \"phpunit.xml\"\n\n# after\n$ vendor/bin/phpunit --configuration /srv/app/phpunit.xml","handlingStrategy":"validation","validationCode":"$config = 'phpunit.xml';\nif (!is_file($config) || !is_readable($config)) {\n    throw new RuntimeException(\"Configuration {$config} missing or unreadable\");\n}","typeGuard":null,"tryCatchPattern":"use PHPUnit\\Util\\Xml\\XmlException;\n\ntry {\n    $document = (new Loader)->loadFile($filename);\n} catch (XmlException $e) {\n    if (str_starts_with($e->getMessage(), 'Could not read XML')) {\n        // path problem: fix or fall back to defaults\n    }\n    throw $e;\n}","preventionTips":["Invoke PHPUnit from the project root so auto-discovery finds phpunit.xml without --configuration","Use absolute paths for --configuration in wrapper scripts and CI","Add `test -r phpunit.xml` to CI preflight steps"],"tags":["phpunit","xml","configuration","file-io"],"backgroundTag":"config-file-unreadable","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}