skylot/jadx · error · JadxOverflowException

Regions count limit reached at block {}

Error message

Regions count limit reached at block {}

What it means

Thrown by RegionMaker.makeRegion when the block-traversal loop produces more than regionsLimit (basicBlocks.size() * 400) regions for a single method. It guards region construction against pathological control-flow explosion that would otherwise exhaust memory or run for minutes. A JadxOverflowException, so it is meant to be catchable and to fail one method, not the whole run.

Source

Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/regions/maker/RegionMaker.java:72

		Region region = new Region(stack.peekRegion());
		if (stack.containsExit(startBlock)) {
			insertEdgeInsns(region, startBlock);
			return region;
		}
		if (processedBlocks.addChecked(startBlock)) {
			// Add block to multiple regions (duplicate the instructions in decompiled code)
			// and allow processing to continue
			if (!startBlock.contains(AFlag.DUPLICATED)) {
				mth.addWarnComment("Code duplicated, block: " + startBlock + ' ' + startBlock.getAttributesString());
				startBlock.add(AFlag.DUPLICATED);
			}
		}
		BlockNode next = startBlock;
		while (next != null) {
			next = traverse(region, next);
			regionsCount++;
			if (regionsCount > regionsLimit) {
				throw new JadxOverflowException("Regions count limit reached at block " + startBlock);
			}
		}
		return region;
	}

	/**
	 * Recursively traverse all blocks from 'block' until block from 'exits'
	 */
	private @Nullable BlockNode traverse(Region r, BlockNode block) {
		if (block.contains(AFlag.MTH_EXIT_BLOCK)) {
			return null;
		}
		BlockNode next = null;
		boolean processed = false;

		List<LoopInfo> loops = block.getAll(AType.LOOP);
		int loopCount = loops.size();
		if (loopCount != 0 && block.contains(AFlag.LOOP_START)) {

View on GitHub (pinned to e738a26571)

Solutions

  1. Update jadx; the multiplier and traversal have been tuned repeatedly.
  2. Report the input with the method name so the region-maker logic can be improved.
  3. Decompile the class with the method excluded, or run with the CLI/GUI 'skip errors' style flow that records the failure as a method warning instead of aborting.
  4. If embedding jadx, catch JadxOverflowException per class/method.

Example fix

// before
ClassNode cls = ...;
new RegionMaker(cls).makeMthRegion();
// after
try {
    new RegionMaker(cls).makeMthRegion();
} catch (JadxOverflowException e) {
    cls.addError("region build overflow", e);
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    cls.decompile();
} catch (JadxOverflowException e) {
    cls.addError("region count overflow", e);
}

Prevention

When it happens

Trigger: Decompiling a method whose CFG, after block merging, causes traverse() to keep returning non-null next blocks and accumulate regions beyond 400 * basicBlocks.size(). Typical of generated state-machine code, huge switch ladders, or methods flattened by obfuscators.

Common situations: Obfuscated apps, methods decompiled from native-to-DEX translators, auto-generated lookup tables encoded as switch/if chains, or methods with many duplicated blocks (the DUPLICATED path above this check is what usually precedes the blow-up).

Related errors


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