skylot/jadx · error · IOException
String read error
Error message
String read error
What it means
Thrown as an IOException by ClsSet.readString(DataInputStream, int) when the input stream returns -1 (EOF) before the expected number of string bytes are read. The method loops reading partial bytes; hitting end-of-stream mid-string indicates a truncated or corrupted .clst file.
Source
Thrown at jadx-core/src/main/java/jadx/core/clsp/ClsSet.java:472
if (len >= 0xFF) {
throw new JadxRuntimeException("String is too long: " + name);
}
writeUnsignedByte(out, bytes.length);
out.write(bytes);
}
private static String readString(DataInputStream in) throws IOException {
int len = readUnsignedByte(in);
return readString(in, len);
}
private static String readString(DataInputStream in, int len) throws IOException {
byte[] bytes = new byte[len];
int count = in.read(bytes);
while (count != len) {
int res = in.read(bytes, count, len - count);
if (res == -1) {
throw new IOException("String read error");
} else {
count += res;
}
}
return new String(bytes, STRING_CHARSET);
}
private static void writeUnsignedByte(DataOutputStream out, int value) throws IOException {
if (value < 0 || value >= 0xFF) {
throw new JadxRuntimeException("Unsigned byte value is too big: " + value);
}
out.writeByte(value);
}
private static int readUnsignedByte(DataInputStream in) throws IOException {
return ((int) in.readByte()) & 0xFF;
}
View on GitHub (pinned to e738a26571)
Solutions
- Delete the corrupted .clst file and regenerate or re-download it from a known-good source.
- Verify file integrity (checksum/size) before loading.
- Ensure the writing and reading jadx versions use the same STRING_CHARSET and length encoding.
Defensive patterns
Strategy: validation
Validate before calling
// Validate file integrity before loading
File clstFile = new File(path);
long expectedSize = ...; // known-good size or checksum
if (clstFile.length() < expectedSize) {
throw new IOException("Possible truncated .clst file: " + path);
}
// Verify checksum
String checksum = DigestUtils.md5Hex(new FileInputStream(clstFile));
if (!checksum.equals(EXPECTED_CHECKSUM)) {
throw new IOException("Checksum mismatch for .clst file");
} Try / catch
try {
clsSet.loadFromClstFile();
} catch (IOException e) {
if (e.getMessage().equals("String read error")) {
logger.error("Corrupted or truncated .clst file. Re-download or regenerate.", e);
}
throw e;
} Prevention
- Verify .clst file checksums after download or generation.
- Use atomic writes (temp file + rename) when generating .clst to avoid truncation.
- Do not load .clst files from untrusted or incomplete sources.
When it happens
Trigger: Reading a .clst file that is shorter than expected — either truncated on disk, partially downloaded, or produced by an interrupted write. A version mismatch causing incorrect length decoding can also make jadx try to read past the actual data.
Common situations: Interrupted or incomplete .clst file generation. Disk corruption or partial file transfer. A version skew where readUnsignedByte decodes a length that doesn't match what was written, causing a read overrun.
Related errors
- Unsupported Arg Type:
- String is too long:
- Classpath already loaded
- Failed to save JSON file: {}
- Failed to save JSON file: {}
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/1a14360f8b566579.
Report an issue: GitHub.