{"record":{"id":"c9693357fe49f829","repo":"jenkinsci/jenkins","slug":"failed-to-parse-xml","errorCode":null,"errorMessage":"Failed to parse XML","messagePattern":"Failed to parse XML","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/hudson/PluginManager.java","lineNumber":2329,"sourceCode":"                        throw new SAXException(\"Malformed plugin attribute: \" + plugin);\n                    }\n                    int at = plugin.indexOf('@');\n                    String shortName = plugin.substring(0, at);\n                    VersionNumber existing = requestedPlugins.get(shortName);\n                    VersionNumber requested = new VersionNumber(plugin.substring(at + 1));\n                    if (existing == null || existing.compareTo(requested) < 0) {\n                        requestedPlugins.put(shortName, requested);\n                    }\n                }\n\n                @Override public InputSource resolveEntity(String publicId, String systemId) throws IOException,\n                        SAXException {\n                    return RestrictiveEntityResolver.INSTANCE.resolveEntity(publicId, systemId);\n                }\n\n            });\n        } catch (SAXException x) {\n            throw new IOException(\"Failed to parse XML\", x);\n        } catch (ParserConfigurationException e) {\n            throw new AssertionError(e); // impossible since we don't tweak XMLParser\n        }\n        return requestedPlugins;\n    }\n\n    @Restricted(DoNotUse.class) // table.jelly\n    public MetadataCache createCache() {\n        return new MetadataCache();\n    }\n\n    /**\n     * Disable a list of plugins using a strategy for their dependents plugins.\n     * @param strategy the strategy regarding how the dependent plugins are processed\n     * @param plugins the list of plugins\n     * @return the list of results for every plugin and their dependent plugins.\n     * @throws IOException see {@link PluginWrapper#disable()}\n     */","sourceCodeStart":2311,"sourceCodeEnd":2347,"githubUrl":"https://github.com/jenkinsci/jenkins/blob/2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc/core/src/main/java/hudson/PluginManager.java#L2311-L2347","documentation":"IOException wrapping a SAXException thrown while parsing a config.xml file to extract requested plugin dependencies. The XML is parsed with a secure SAXParser (disallowing DOCTYPE declarations and enabling secure processing). Any malformed XML, unexpected encoding, or XML structure violation triggers this.","triggerScenarios":"config.xml content that is not well-formed XML, contains invalid characters, has encoding issues, or triggers a SAX parse error during the dependency extraction pass.","commonSituations":"Corrupted or truncated config.xml file (e.g., from a disk-full write, interrupted save), manually edited XML with syntax errors, or a config.xml from an incompatible Jenkins version with unexpected structure.","solutions":["Validate the config.xml file with an XML validator (xmllint, an IDE) before loading.","Restore config.xml from backup if corrupted.","Check file encoding — must be valid UTF-8.","Inspect the wrapped SAXException (e.getCause()) for line/column of the parse error."],"exampleFix":"# before — config.xml has a syntax error (unclosed tag)\n# <project> ... (missing </project>)\n\n# fix\nxmllint --noout config.xml  # validate\n# correct the XML structure, then reload","handlingStrategy":"try-catch","validationCode":"// Validate XML well-formedness before passing to parseRequestedPlugins\ntry {\n    DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(configXml);\n} catch (Exception e) {\n    throw new IllegalArgumentException(\"config.xml is not well-formed XML: \" + e.getMessage(), e);\n}","typeGuard":null,"tryCatchPattern":"try {\n    Map<String, VersionNumber> deps = pluginManager.parseRequestedPlugins(configXml);\n} catch (IOException e) {\n    Throwable cause = e.getCause();\n    listener.error(\"Failed to parse config.xml: \" + (cause != null ? cause.getMessage() : e.getMessage()));\n    // recover from backup or skip plugin dependency resolution\n}","preventionTips":["Validate config.xml with xmllint or an XML parser before loading.","Keep backups of config.xml to restore from corruption.","Ensure config.xml is saved atomically (write to temp, rename) to avoid truncation."],"tags":["plugin-manager","xml","parsing","sax","corruption"],"backgroundTag":null,"analyzedSha":"2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc","analyzedAt":"2026-08-14T07:07:15.274Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}