skylot/jadx · error · JadxRuntimeException

Incorrect negative register number in instruction: {}

Error message

Incorrect negative register number in instruction: {}

What it means

Thrown by CheckCode.checkInstructions() when iterating every register referenced by an instruction and finding one whose register number is negative. Register numbers must be non-negative integers in valid Dalvik bytecode; a negative value indicates the instruction was built incorrectly during earlier decoding or that the DEX file is corrupt.

Source

Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/CheckCode.java:76

		if (isEmpty(mth.getInstructions())) {
			return;
		}
		int regsCount = mth.getRegsCount();
		List<RegisterArg> list = new ArrayList<>();
		for (InsnNode insnNode : mth.getInstructions()) {
			if (insnNode == null) {
				continue;
			}
			list.clear();
			RegisterArg resultArg = insnNode.getResult();
			if (resultArg != null) {
				list.add(resultArg);
			}
			insnNode.getRegisterArgs(list);
			for (RegisterArg arg : list) {
				int regNum = arg.getRegNum();
				if (regNum < 0) {
					throw new JadxRuntimeException("Incorrect negative register number in instruction: " + insnNode);
				}
				if (regNum >= regsCount) {
					throw new JadxRuntimeException("Incorrect register number in instruction: " + insnNode
							+ ", expected to be less than " + regsCount);
				}
			}
		}
	}
}

View on GitHub (pinned to e738a26571)

Solutions

  1. Upgrade jadx — instruction decoding and register handling are regularly fixed.
  2. Catch JadxRuntimeException around per-class decompilation to avoid aborting the whole batch.
  3. Report the issue with the instruction dump from the error message and the offending DEX.
  4. If the DEX is corrupt, re-verify with dexdump or baksmali and obtain a non-corrupt copy.
Defensive patterns

Strategy: try-catch

Validate before calling

// Basic DEX integrity sanity check before decompiling
import java.io.File;
import java.io.FileInputStream;

boolean looksLikeValidDex(File f) throws IOException {
    try (FileInputStream fis = new FileInputStream(f)) {
        byte[] magic = new byte[8];
        if (fis.read(magic) < 8) return false;
        // DEX magic: 'dex\n' followed by version and '\0'
        return magic[0] == 'd' && magic[1] == 'e' && magic[2] == 'x' && magic[3] == '\n';
    }
}

Try / catch

try {
    jadx.load();
    jadx.save();
} catch (JadxRuntimeException e) {
    // Catch at the batch level; consider per-class fallback
    LOG.error("Decompilation failed (register validation): {}", e.getMessage());
}

Prevention

When it happens

Trigger: CheckCode.visit() runs on a MethodNode, iterates mth.getInstructions(), collects result + source register args, and for some RegisterArg arg.getRegNum() < 0. This can happen if a register arg was created with an unset/default register number, or if a bytecode rewriter emitted an instruction with a malformed register operand.

Common situations: Corrupt or tampered DEX files, DEX produced by non-standard tools, or edge cases where jadx's own instruction decoder mis-parses a register slot. Rare with output from standard Android build tools (d8/r8).

Related errors


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