skylot/jadx · error · DecodeException

Wrong jadx class set header

Error message

Wrong jadx class set header

What it means

Thrown by ClsSet.load when the header bytes of a .jcst file do not match the expected constant 'jadx-cst' (JADX_CLS_SET_HEADER). The method reads exactly header.length bytes and compares as a US-ASCII string. A mismatch or short read indicates the file is not a valid jadx class set file — it may be a different format, truncated, or corrupted.

Source

Thrown at jadx-core/src/main/java/jadx/core/clsp/ClsSet.java:313

			writeArgTypesList(out, argType.getExtendTypes(), names);
		} else if (argType.isObject()) {
			out.writeByte(TypeEnum.OBJECT.ordinal());
			out.writeInt(getCls(argType, names).getId());
		} else if (argType.isArray()) {
			out.writeByte(TypeEnum.ARRAY.ordinal());
			writeArgType(out, argType.getArrayElement(), names);
		} else {
			throw new JadxRuntimeException("Cannot save type: " + argType);
		}
	}

	private void load(InputStream input) throws IOException, DecodeException {
		try (DataInputStream in = new DataInputStream(new BufferedInputStream(input))) {
			byte[] header = new byte[JADX_CLS_SET_HEADER.length()];
			int readHeaderLength = in.read(header);
			if (readHeaderLength != JADX_CLS_SET_HEADER.length()
					|| !JADX_CLS_SET_HEADER.equals(new String(header, STRING_CHARSET))) {
				throw new DecodeException("Wrong jadx class set header");
			}
			int version = in.readByte();
			if (version != VERSION) {
				throw new DecodeException("Wrong jadx class set version, got: " + version + ", expect: " + VERSION);
			}
			androidApiLevel = in.readInt();
			int clsCount = in.readInt();
			classes = new ClspClass[clsCount];
			for (int i = 0; i < clsCount; i++) {
				int accFlags = in.readInt();
				ClspClassSource clsSource = readClsSource(in);
				String name = readString(in);
				classes[i] = new ClspClass(ArgType.object(name), i, accFlags, clsSource);
			}
			for (int i = 0; i < clsCount; i++) {
				ClspClass nClass = classes[i];
				ClassInfo clsInfo = ClassInfo.fromType(root, nClass.getClsType());
				nClass.setParents(readArgTypesArray(in));

View on GitHub (pinned to e738a26571)

Solutions

  1. Verify the file starts with the ASCII bytes 'jadx-cst' (hex 6a 61 64 78 2d 63 73 74) using a hex editor or xxd.
  2. Ensure the .jcst file was produced by ClsSet.save from a compatible jadx version — do not substitute other formats.
  3. If the bundled core.jcst is corrupted, rebuild or re-download jadx-core to restore the resource.
  4. Catch DecodeException around the load call and report the invalid file to the user with a clear 'not a valid jadx class set file' message.
Defensive patterns

Strategy: validation

Validate before calling

// Validate the file header before passing to ClsSet.load
try (InputStream check = Files.newInputStream(path)) {
    byte[] header = new byte[8];
    int read = check.read(header);
    if (read != 8 || !new String(header, "US-ASCII").equals("jadx-cst")) {
        throw new IllegalArgumentException(
            "File is not a valid jadx class set (.jcst) file");
    }
}

Type guard

static boolean hasJadxCstHeader(Path path) throws IOException {
    try (InputStream in = Files.newInputStream(path)) {
        byte[] header = new byte[8];
        int read = in.read(header);
        return read == 8 && new String(header, java.nio.charset.StandardCharsets.US_ASCII).equals("jadx-cst");
    }
}

Try / catch

try {
    clsSet.loadFromClstFile();
} catch (DecodeException e) {
    if (e.getMessage().equals("Wrong jadx class set header")) {
        throw new IllegalArgumentException(
            "The .jcst file is corrupt or not a jadx class set file", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling ClsSet.load(input) (indirectly via loadFromClstFile for the bundled resource, or directly on a user-supplied stream) where the stream does not begin with the ASCII bytes 'jadx-cst'. The check also fails if readHeaderLength is shorter than the expected 8 bytes (truncated file or empty stream).

Common situations: Pointing jadx at a custom .jcst file that is actually a JAR, ZIP, or other binary. A corrupted or partially written .jcst file from an interrupted save operation. Using an incompatible file from a different tool that also uses the .jcst extension. A truncated download of the classpath file.

Related errors


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