skylot/jadx · error · RuntimeException

Failed to parse xml

Error message

Failed to parse xml

What it means

Thrown by JadxSecurity.parseXml when the underlying DocumentBuilder.parse(in) call fails for any reason (SAXException, IOException, IllegalArgumentException, etc.). Jadx wraps all exceptions in a generic RuntimeException because parseXml is called from multiple code paths (AndroidManifest.xml, resource XML, etc.) that do not declare checked exceptions. The secure vs. simple factory is selected by the SECURE_XML_PARSER flag but both paths share the same catch.

Source

Thrown at jadx-core/src/main/java/jadx/api/security/impl/JadxSecurity.java:113

		Matcher matcher = SANITIZE_GRADLE_PATTERN.matcher(str);
		if (matcher.find()) {
			return matcher.replaceAll("");
		}
		return str;
	}

	@Override
	public Document parseXml(InputStream in) {
		DocumentBuilderFactory dbf;
		if (flags.contains(JadxSecurityFlag.SECURE_XML_PARSER)) {
			dbf = SecureDBFHolder.INSTANCE;
		} else {
			dbf = SimpleDBFHolder.INSTANCE;
		}
		try {
			return dbf.newDocumentBuilder().parse(in);
		} catch (Exception e) {
			throw new RuntimeException("Failed to parse xml", e);
		}
	}

	private static final class SimpleDBFHolder {
		private static final DocumentBuilderFactory INSTANCE = DocumentBuilderFactory.newInstance();
	}

	private static final class SecureDBFHolder {
		private static final DocumentBuilderFactory INSTANCE = buildSecureDBF();

		private static DocumentBuilderFactory buildSecureDBF() {
			try {
				DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
				dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
				dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
				dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
				dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
				dbf.setFeature("http://apache.org/xml/features/dom/create-entity-ref-nodes", false);

View on GitHub (pinned to e738a26571)

Solutions

  1. Inspect getCause() — a SAXException indicates malformed XML content; an IOException indicates stream reading failure.
  2. Validate the input is well-formed text XML before calling parseXml, especially if the source may be binary AXML (convert it first with the AXML decoder).
  3. If the SECURE_XML_PARSER flag is set and DTD/external entities are legitimately needed (rare), disable that flag — but be aware of XXE risks.
  4. Catch the RuntimeException around parseXml and log the offending resource name so processing of the rest of the APK can continue.

Example fix

// before
Document doc = jadxSecurity.parseXml(inputStream);

// after: validate and handle
Document doc;
try {
    doc = jadxSecurity.parseXml(inputStream);
} catch (RuntimeException e) {
    LOG.warn("Failed to parse XML resource", e.getCause());
    doc = null; // or skip resource
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate that the stream contains text XML, not binary AXML
byte[] first = new byte[5];
inputStream.mark(5);
int read = inputStream.read(first);
inputStream.reset();
if (read >= 1 && first[0] == 0x03) { // binary AXML magic number
    throw new IllegalArgumentException("Input is binary AXML, not text XML — convert first");
}

Try / catch

Document doc;
try {
    doc = jadxSecurity.parseXml(inputStream);
} catch (RuntimeException e) {
    Throwable cause = e.getCause();
    if (cause instanceof org.xml.sax.SAXException) {
        LOG.warn("Malformed XML: {}", cause.getMessage());
    } else if (cause instanceof java.io.IOException) {
        LOG.warn("IO error reading XML: {}", cause.getMessage());
    }
    doc = null;
}

Prevention

When it happens

Trigger: Calling parseXml(in) with a stream containing malformed XML, non-XML binary data, truncated content, or an unsupported encoding declaration. Also triggered if the InputStream throws IOException during reading, or if the input is null (though a null stream typically yields a different NullPointerException before the catch). The secure parser may additionally reject XML with DTD or external entity references.

Common situations: Decompiling an APK whose AndroidManifest.xml or resources.arsc XML is corrupted or obfuscated. Binary XML (AXML format) fed to parseXml instead of text XML. A truncated or partially downloaded APK where the XML resource is incomplete. Custom jadx integrations that pass unvalidated streams to parseXml.

Understand the failure class

Related errors


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/28290651ad04892c. Report an issue: GitHub.