skylot/jadx · error · JadxRuntimeException
Failed to load config file: {}
Error message
Failed to load config file: {} What it means
Thrown by SmaliDebugger.handShake when writing the JDWP handshake bytes to the output stream or reading the 14-byte handshake reply from the input stream raises any exception (it catches broad Exception). It means the underlying transport failed during the JDWP handshake exchange itself: the peer reset the connection, the stream hit EOF, or the 5-second socket timeout elapsed before 14 bytes arrived.
Source
Thrown at jadx-cli/src/main/java/jadx/cli/config/JadxConfigAdapter.java:73
}
public Path getConfigPath() {
return configPath;
}
public String getDefaultConfigFileName() {
return defaultConfigFileName;
}
public @Nullable T load() {
if (!Files.isRegularFile(configPath)) {
// file not found
return null;
}
try (JsonReader reader = gson.newJsonReader(Files.newBufferedReader(configPath))) {
return gson.fromJson(reader, configCls);
} catch (Exception e) {
throw new JadxRuntimeException("Failed to load config file: " + configPath, e);
}
}
public void save(T configObject) {
try {
String jsonStr = gson.toJson(configObject, configCls);
// don't use stream writer here because serialization errors will corrupt config
Files.writeString(configPath, jsonStr);
} catch (Exception e) {
throw new JadxRuntimeException("Failed to save config file: " + configPath, e);
}
}
public String objectToJsonString(T configObject) {
return gson.toJson(configObject, configCls);
}
public T jsonStringToObject(String jsonStr) {View on GitHub (pinned to e738a26571)
Solutions
- Re-establish the ADB jdwp forward for the live process id and retry attach.
- Confirm the target app/process is still alive at attach time (not yet crashed or exited).
- Make sure only one debugger attaches; jdwp accepts a single handshake client per session.
- Inspect the wrapped cause: SocketException/EOFException points to a dead/unreachable peer, SocketTimeoutException to a slow/unresponsive one.
Defensive patterns
Strategy: retry
Validate before calling
// Before attach, confirm a TCP peer is listening and is a jdwp agent:
try (Socket s = new Socket()) {
s.connect(new InetSocketAddress(host, port), 2000);
s.setSoTimeout(2000);
s.getOutputStream().write(JDWP.encodeHandShakePacket());
byte[] reply = IOUtils.readNBytes(s.getInputStream(), 14);
if (reply == null || !JDWP.decodeHandShakePacket(reply)) {
throw new IllegalStateException("No jdwp agent on " + host + ":" + port);
}
} Try / catch
// handShake runs inside attach; handle at the attach boundary
try {
return SmaliDebugger.attach(host, port, listener);
} catch (SmaliDebuggerException e) {
Throwable cause = e.getCause();
boolean transientNet = cause instanceof java.net.SocketTimeoutException
|| cause instanceof java.net.SocketException
|| cause instanceof java.io.EOFException;
if (transientNet) {
ensureJdwpForward(packageName, port);
return SmaliDebugger.attach(host, port, listener); // retry once
}
throw e;
} Prevention
- Establish the jdwp forward fresh right before attach.
- Attach while the target process is alive; re-attach if it restarted.
- Use a single debugger per jdwp session.
- Differentiate refused/EOF (dead peer) from timeout (slow peer) via the wrapped cause.
When it happens
Trigger: handShake writes JDWP.encodeHandShakePacket() then IOUtils.readNBytes(in, 14). A connection reset, EOF, or socket-read timeout during that exchange is wrapped here. Fires at the very start of initJDWP, before any command packets are sent.
Common situations: The forwarded port has no jdwp listener (immediate reset), the target process died mid-handshake, the device USB link dropped, the socket timeout (5000ms) is too short for a slow device, or another client already consumed the jdwp endpoint.
Related errors
- Failed to save config file: {}
- Found {} classes, single class output can't be used
- Input class can't be saved by current jadx settings (marked
- Class decompilation failed
- Unknown option: {}
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/f542993e36937744.
Report an issue: GitHub.