skylot/jadx · error · IOException

Config size < 4

Error message

Config size < 4

What it means

parseConfig reads the size field of a ResTable_config structure. The first 4 bytes encode the total config size; if it is less than 4, the structure is too small to even contain its own size field, indicating corrupt or invalid config data.

Source

Thrown at jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java:541

	private RawNamedValue parseValueMap() throws IOException {
		int nameRef = is.readInt32();
		return new RawNamedValue(nameRef, parseValue());
	}

	private RawValue parseValue() throws IOException {
		is.checkInt16(8, "value size");
		is.checkInt8(0, "value res0 not 0");
		int dataType = is.readInt8();
		int data = is.readInt32();
		return new RawValue(dataType, data);
	}

	private EntryConfig parseConfig() throws IOException {
		long start = is.getPos();
		int size = is.readInt32();
		if (size < 4) {
			throw new IOException("Config size < 4");
		}

		// Android zero fill this structure and only read the data present
		var configData = new byte[Math.max(52, size - 4)];
		is.readFully(configData, 0, size - 4);
		var configIs = new ParserStream(new ByteArrayInputStream(configData));

		short mcc = (short) configIs.readInt16();
		short mnc = (short) configIs.readInt16();

		char[] language = unpackLocaleOrRegion((byte) configIs.readInt8(), (byte) configIs.readInt8(), 'a');
		char[] country = unpackLocaleOrRegion((byte) configIs.readInt8(), (byte) configIs.readInt8(), '0');

		byte orientation = (byte) configIs.readInt8();
		byte touchscreen = (byte) configIs.readInt8();
		int density = configIs.readInt16();

		byte keyboard = (byte) configIs.readInt8();

View on GitHub (pinned to e738a26571)

Solutions

  1. Re-extract resources.arsc from a valid APK
  2. Upgrade jadx to the latest version
  3. Report the file to jadx maintainers with context
  4. Use --no-res to skip resource decoding entirely

Example fix

// Skip resources:
jadxArgs.setSkipResources(true);
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the arsc file has enough data for config structures
if (Files.size(arscPath) < 52) { throw new IllegalArgumentException("arsc too small for config"); }

Try / catch

try {
    resTableParser.decode(stream);
} catch (IOException e) {
    if (e.getMessage().contains("Config size")) {
        LOG.warn("Invalid config in resources, skipping", e);
        jadxArgs.setSkipResources(true);
    }
}

Prevention

When it happens

Trigger: parseConfig() reads an int32 size from the stream. The Android resource format guarantees config is at least 4 bytes (the size field itself). A value < 4 means the data is garbage, truncated, or misaligned. This is a defensive guard before allocating a config data buffer.

Common situations: Corrupt resources.arsc where config size fields are zeroed or negative (interpreted as unsigned). Obfuscation tools that mangle config entries. Truncated resource data stream. Passing a non-resource binary to the parser.

Related errors


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