skylot/jadx · error · DecodeException
Unknown instruction: '{}'
Error message
Unknown instruction: '{}' What it means
The default branch of the main opcode switch in InsnDecoder.decode(). It fires when a DEX instruction opcode is encountered that is not in any handled case (everything up through MONITOR_EXIT). Represents an opcode JADX does not know how to translate.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java:514
case SPARSE_SWITCH:
return makeSwitch(insn, false);
case PACKED_SWITCH_PAYLOAD:
case SPARSE_SWITCH_PAYLOAD:
return new SwitchData((ISwitchPayload) insn.getPayload());
case MONITOR_ENTER:
return insn(InsnType.MONITOR_ENTER,
null,
InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT));
case MONITOR_EXIT:
return insn(InsnType.MONITOR_EXIT,
null,
InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT));
default:
throw new DecodeException("Unknown instruction: '" + insn + '\'');
}
}
private SwitchInsn makeSwitch(InsnData insn, boolean packed) {
SwitchInsn swInsn = new SwitchInsn(InsnArg.reg(insn, 0, ArgType.NARROW_INTEGRAL), insn.getTarget(), packed);
ICustomPayload payload = insn.getPayload();
if (payload != null) {
swInsn.attachSwitchData(new SwitchData((ISwitchPayload) payload), insn.getTarget());
}
method.add(AFlag.COMPUTE_POST_DOM);
CodeFeaturesAttr.add(method, CodeFeature.SWITCH);
return swInsn;
}
private InsnNode makeNewArray(InsnData insn) {
ArgType indexType = ArgType.parse(insn.getIndexAsType());
// NEW_ARRAY literal = dimensions to wrap the operand by: 0 if it is already the full array type
// (dalvik new-array, java multianewarray), 1 for newarray/anewarray (operand is the element type)View on GitHub (pinned to e738a26571)
Solutions
- Upgrade JADX to a version that supports the target DEX format / Android API level.
- Verify the DEX file with dexdump or baksmali to confirm the opcode is genuinely unknown vs. corrupt.
- Use --no-replace-consts or other fallback flags and skip the offending class with -j 1 per-class runs.
- File an issue with the raw opcode value and the instruction offset.
Defensive patterns
Strategy: try-catch
Validate before calling
// Before a batch run, confirm the DEX format version is one JADX supports.
byte[] magic = Files.readAllBytes(Path.of("classes.dex")).length >= 8
? Files.readAllBytes(Path.of("classes.dex")) : new byte[0];
boolean admissible = magic.length >= 8 && (magic[0] == 0x64 && magic[1] == 0x65 && magic[2] == 0x78);
if (!admissible) throw new IllegalArgumentException("Not a valid DEX file"); Try / catch
try {
jadx.load();
} catch (JadxRuntimeException e) {
if (e.getMessage().contains("Unknown instruction")) {
log.warn("Unsupported opcode encountered; upgrade JADX", e);
} else throw e;
} Prevention
- Match the JADX version to the DEX format / Android API level of your input.
- Validate DEX files with dexdump before decompiling.
- Run per-class so unknown opcodes in one class do not abort the whole APK.
When it happens
Trigger: A DEX bytecode opcode value not covered by the switch — e.g. a reserved/unassigned opcode, an opcode from a future DEX format, or a value produced by a corrupt or deliberately mangled code section.
Common situations: Decompiling an APK built for an Android version newer than what JADX supports, DEX files generated by non-standard toolchains, or obfuscators that corrupt opcode bytes.
Related errors
- Failed to decode insn: {}
- Input class not found: {}
- Unsupported Arg Type:
- Failed to load method reference for insn: {}
- Failed to get call site for insn: {}
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/d18b35b7d336d34d.
Report an issue: GitHub.