{"record":{"id":"8b6e74d9175c4de9","repo":"elastic/elasticsearch","slug":"error-parsing-xml-report-xmlreportfileabsolutepa","errorCode":null,"errorMessage":"Error parsing xml report ${xmlReportFileAbsolutePath}","messagePattern":"Error parsing xml report (.+?)","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/precommit/LicenseHeadersTask.java","lineNumber":337,"sourceCode":"        writer.close();\n        return stats;\n    }\n\n    private static List<String> unapprovedFiles(File xmlReportFile) {\n        try {\n            NodeList resourcesNodes = createXmlDocumentBuilderFactory().newDocumentBuilder()\n                .parse(xmlReportFile)\n                .getElementsByTagName(\"resource\");\n            return elementList(resourcesNodes).stream()\n                .filter(\n                    resource -> elementList(resource.getChildNodes()).stream()\n                        .anyMatch(n -> n.getTagName().equals(\"license-approval\") && n.getAttribute(\"name\").equals(\"false\"))\n                )\n                .map(e -> e.getAttribute(\"name\"))\n                .sorted()\n                .collect(Collectors.toList());\n        } catch (SAXException | IOException | ParserConfigurationException e) {\n            throw new GradleException(\"Error parsing xml report \" + xmlReportFile.getAbsolutePath());\n        }\n    }\n\n    private static DocumentBuilderFactory createXmlDocumentBuilderFactory() throws ParserConfigurationException {\n        final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n        dbf.setXIncludeAware(false);\n        dbf.setIgnoringComments(true);\n        dbf.setExpandEntityReferences(false);\n        dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, \"\");\n        dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, \"\");\n        dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);\n        dbf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n        dbf.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n        dbf.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n        dbf.setFeature(\"http://apache.org/xml/features/nonvalidating/load-external-dtd\", false);\n        return dbf;\n    }\n","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/precommit/LicenseHeadersTask.java#L319-L355","documentation":"After generating the RAT XML report, unapprovedFiles parses it with a secured DocumentBuilderFactory to list resources whose license-approval is false. If the parse fails (SAXException, IOException, or ParserConfigurationException) this GradleException is thrown. Notably the original exception is not attached as a cause, which makes diagnosis harder.","triggerScenarios":"The XML report file is empty, truncated, or malformed when DocumentBuilder.parse runs; the JAXP configuration rejects the secured features (ParserConfigurationException); the report file was deleted between generation and parsing.","commonSituations":"A previous generateReport wrote a partial/corrupt file (disk full, interrupted); an XML parser feature unsupported by the runtime JDK; the reportFile was concurrently modified; antivirus quarantined the XML.","solutions":["Open the report file at the printed path and check it is well-formed XML.","Delete the report and rerun with `--rerun-tasks` to regenerate it cleanly.","If ParserConfigurationException, check the JDK vendor/version supports disallow-doctype-decl and FEATURE_SECURE_PROCESSING.","Free disk space if the file is truncated."],"exampleFix":"// before: truncated report from a previous failed run\nrm build/reports/licenseHeaders/rat.xml && ./gradlew licenseHeaders --rerun-tasks","handlingStrategy":"validation","validationCode":"File xml = reportFile.getAsFile().get();\nif (!xml.isFile() || xml.length() == 0) {\n    throw new GradleException(\"RAT XML report missing or empty: \" + xml);\n}\n// Optionally validate well-formedness before parsing\nDocumentBuilderFactory dbf = createXmlDocumentBuilderFactory();\ndbf.newDocumentBuilder().parse(xml);","typeGuard":null,"tryCatchPattern":"try {\n    return unapprovedFiles(xmlReportFile);\n} catch (GradleException e) {\n    // The wrapper drops the cause; re-open the file to diagnose\n    if (!xmlReportFile.isFile()) { throw new GradleException(\"Report vanished: \" + xmlReportFile); }\n    throw e;\n}","preventionTips":["Always regenerate the report in the same invocation that parses it (avoid leftover files).","Run with --rerun-tasks after a disk-full or interrupted build.","Confirm the runtime JDK supports the secured JAXP features the factory sets."],"tags":["gradle","license","xml","precommit","report"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}