{"record":{"id":"008ca9d64c9580fc","repo":"skylot/jadx","slug":"wrong-jadx-class-set-header","errorCode":null,"errorMessage":"Wrong jadx class set header","messagePattern":"Wrong jadx class set header","errorType":"exception","errorClass":"DecodeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/clsp/ClsSet.java","lineNumber":313,"sourceCode":"\t\t\twriteArgTypesList(out, argType.getExtendTypes(), names);\n\t\t} else if (argType.isObject()) {\n\t\t\tout.writeByte(TypeEnum.OBJECT.ordinal());\n\t\t\tout.writeInt(getCls(argType, names).getId());\n\t\t} else if (argType.isArray()) {\n\t\t\tout.writeByte(TypeEnum.ARRAY.ordinal());\n\t\t\twriteArgType(out, argType.getArrayElement(), names);\n\t\t} else {\n\t\t\tthrow new JadxRuntimeException(\"Cannot save type: \" + argType);\n\t\t}\n\t}\n\n\tprivate void load(InputStream input) throws IOException, DecodeException {\n\t\ttry (DataInputStream in = new DataInputStream(new BufferedInputStream(input))) {\n\t\t\tbyte[] header = new byte[JADX_CLS_SET_HEADER.length()];\n\t\t\tint readHeaderLength = in.read(header);\n\t\t\tif (readHeaderLength != JADX_CLS_SET_HEADER.length()\n\t\t\t\t\t|| !JADX_CLS_SET_HEADER.equals(new String(header, STRING_CHARSET))) {\n\t\t\t\tthrow new DecodeException(\"Wrong jadx class set header\");\n\t\t\t}\n\t\t\tint version = in.readByte();\n\t\t\tif (version != VERSION) {\n\t\t\t\tthrow new DecodeException(\"Wrong jadx class set version, got: \" + version + \", expect: \" + VERSION);\n\t\t\t}\n\t\t\tandroidApiLevel = in.readInt();\n\t\t\tint clsCount = in.readInt();\n\t\t\tclasses = new ClspClass[clsCount];\n\t\t\tfor (int i = 0; i < clsCount; i++) {\n\t\t\t\tint accFlags = in.readInt();\n\t\t\t\tClspClassSource clsSource = readClsSource(in);\n\t\t\t\tString name = readString(in);\n\t\t\t\tclasses[i] = new ClspClass(ArgType.object(name), i, accFlags, clsSource);\n\t\t\t}\n\t\t\tfor (int i = 0; i < clsCount; i++) {\n\t\t\t\tClspClass nClass = classes[i];\n\t\t\t\tClassInfo clsInfo = ClassInfo.fromType(root, nClass.getClsType());\n\t\t\t\tnClass.setParents(readArgTypesArray(in));","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java#L295-L331","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["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.","Ensure the .jcst file was produced by ClsSet.save from a compatible jadx version — do not substitute other formats.","If the bundled core.jcst is corrupted, rebuild or re-download jadx-core to restore the resource.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the file header before passing to ClsSet.load\ntry (InputStream check = Files.newInputStream(path)) {\n    byte[] header = new byte[8];\n    int read = check.read(header);\n    if (read != 8 || !new String(header, \"US-ASCII\").equals(\"jadx-cst\")) {\n        throw new IllegalArgumentException(\n            \"File is not a valid jadx class set (.jcst) file\");\n    }\n}","typeGuard":"static boolean hasJadxCstHeader(Path path) throws IOException {\n    try (InputStream in = Files.newInputStream(path)) {\n        byte[] header = new byte[8];\n        int read = in.read(header);\n        return read == 8 && new String(header, java.nio.charset.StandardCharsets.US_ASCII).equals(\"jadx-cst\");\n    }\n}","tryCatchPattern":"try {\n    clsSet.loadFromClstFile();\n} catch (DecodeException e) {\n    if (e.getMessage().equals(\"Wrong jadx class set header\")) {\n        throw new IllegalArgumentException(\n            \"The .jcst file is corrupt or not a jadx class set file\", e);\n    }\n    throw e;\n}","preventionTips":["Verify the file starts with ASCII 'jadx-cst' using a hex editor before loading.","Ensure .jcst files are produced by ClsSet.save, not substituted from other tools.","If the bundled core.jcst is corrupt, rebuild or re-download jadx-core."],"tags":["classpath","clst","serialization","file-format","decode"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}