skylot/jadx · error · JadxRuntimeException

Can not parse xml content

Error message

Can not parse xml content

What it means

AndroidManifestParser.parseXml() wraps any exception from the secure XML parser (IJadxSecurity.parseXml) when decoding manifest or app-string XML content into a DOM Document. The original exception is attached as the cause. It means the XML bytes could not be parsed as well-formed XML - typically because binary/AXML content was not fully converted to textual XML, the content is truncated, or it contains constructs the secure parser rejects (e.g. external entities blocked for security).

Source

Thrown at jadx-core/src/main/java/jadx/core/utils/android/AndroidManifestParser.java:219

					isLauncherCategory = true;
					break;
				}
			}

			if (isMainAction && isLauncherCategory) {
				return true;
			}
		}
		return false;
	}

	private Document parseXml(String xmlContent) {
		try (InputStream xmlStream = new ByteArrayInputStream(xmlContent.getBytes(StandardCharsets.UTF_8))) {
			Document document = security.parseXml(xmlStream);
			document.getDocumentElement().normalize();
			return document;
		} catch (Exception e) {
			throw new JadxRuntimeException("Can not parse xml content", e);
		}
	}

	private @Nullable Document parseAppStrings(@Nullable ResContainer appStrings) {
		if (appStrings == null) {
			return null;
		}
		String content = appStrings.getText().getCodeStr();
		return parseXml(content);
	}

	private @Nullable Document parseAndroidManifest(ResourceFile androidManifest) {
		if (androidManifest == null) {
			return null;
		}
		String content = androidManifest.loadContent().getText().getCodeStr();
		return parseXml(content);
	}

View on GitHub (pinned to e738a26571)

Solutions

  1. Inspect getCause() on the JadxRuntimeException for the precise SAXE/IOException and the offending line/column.
  2. Upgrade jadx - AXML/binary-XML decoding improvements ship regularly.
  3. Re-obtain/re-sign the APK from a trusted source if the input is corrupt.
  4. Skip manifest/app-string parsing if not needed and continue with code-only decompilation.

Example fix

// before
Document doc = parser.parse(); // parseXml throws on bad content
// after - tolerate malformed XML and degrade gracefully
try {
    Document doc = parser.parse();
} catch (JadxRuntimeException e) {
    LOG.warn("Manifest XML parse failed, skipping: {}", e.getCause().getMessage());
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Lightweight well-formedness sniff before handing to the secure parser.
String s = xmlContent.trim();
if (s.isEmpty() || !(s.startsWith("<") || s.startsWith("\uFEFF<"))) {
    throw new IllegalArgumentException("Content does not look like XML");
}

Try / catch

Document doc;
try {
    doc = parser.parse();
} catch (JadxRuntimeException e) {
    LOG.warn("XML parse failed ({}); skipping", e.getCause() == null ? "" : e.getCause().toString());
    doc = null;
}

Prevention

When it happens

Trigger: parseXml(xmlContent) called with bytes that fail DocumentBuilderFactory parsing: malformed XML, partially-decoded binary AXML, truncation, or a security-policy rejection (XXE guard). Used by parseAndroidManifest() and parseAppStrings().

Common situations: A binary AndroidManifest that was not fully converted to text before parsing; an obfuscated APK with deliberately corrupted resources.arsc/strings.xml; a resource produced by a non-standard packager; very large or truncated resource content.

Related errors


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