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
- Re-extract resources.arsc from a valid APK
- Upgrade jadx to the latest version
- Report the file to jadx maintainers with context
- 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
- Ensure the APK is complete and uncorrupted
- Use --no-res fallback
- Keep jadx updated for format robustness
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
- {}, expected: 0x{}, actual: 0x{}, offset: 0x{}
- {}, expected offset: 0x{}, actual: 0x{}
- {}, expected offset not reachable: 0x{}, actual: 0x{}
- Error reading type spec chunk at offset 0x%x
- reading after chunk end
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/dd2616c9823ca457.
Report an issue: GitHub.