MuntashirAkon/AppManager · error · java.io.IOException

Could not connect to ADB.

Error message

Could not connect to ADB.

What it means

LocalServerManager.openAdbShell attempts an ADB connection to the local ADB daemon (wireless debugging) and throws IOException when AdbConnectionManager.connect() fails. This means the app could not establish a socket connection to adbd, which is required to start or stop the local server over ADB.

Solutions

  1. Re-enable Wireless debugging in Developer options and re-check the current port shown there
  2. Update the ADB host/port in the app's server settings to the newly advertised port
  3. Re-pair the app with the device (pairing code) if pairing was invalidated
  4. Verify adbd is listening (adb devices from a PC) and that developer options/USB debugging is active
  5. Retry the operation, as the code disconnects stale sessions before connecting

Example fix

// before
manager.connect(adbHost, adbPort);
// after
if (!manager.connect(adbHost, adbPort)) {
    // prompt user to re-enable wireless debugging / refresh port
    throw new IOException("Could not connect to ADB at " + adbHost + ":" + adbPort + ". Re-enable Wireless debugging and update the port.");
}
Defensive patterns

Strategy: retry

Validate before calling

// check wireless debugging state and port before connecting
if (!isWirelessDebuggingEnabled(context)) {
    throw new IOException("Wireless debugging is disabled.");
}
int currentPort = getLatestAdbPort(); // refresh, port changes on re-enable

Try / catch

try {
    shell = openAdbShell();
} catch (IOException e) {
    // prompt user to re-enable wireless debugging / refresh port, then retry once
}

Prevention

When it happens

Trigger: Calling useAdbStartServer or stopServer when the ADB daemon is unreachable: wireless debugging disabled, wrong adbHost/adbPort, daemon restarted with a new port, or connect() failing after a 10s timeout.

Common situations: Wireless debugging toggled off; phone rebooted so adbd picked a different pairing/connect port; developer options disabled; firewall or VPN blocking the local socket; stale saved ADB port in app settings.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/c41b2345b261b380. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/servermanager/LocalServerManager.java:281

            String command = ServerConfig.getServerRunnerCommand();
            Log.d(TAG, "useAdbStartServer: %s", command);
            executeAdbCommand(is, os, command, "Success!", 1, TimeUnit.MINUTES);
        }
        Log.d(TAG, "useAdbStartServer: Server has started.");
    }

    @WorkerThread
    @NonNull
    private AdbStream openAdbShell() throws Exception {
        String adbHost = ServerConfig.getAdbHost(mContext);
        int adbPort = ServerConfig.getAdbPort();
        AdbConnectionManager manager = AdbConnectionManager.getInstance();
        Log.d(TAG, "Connecting to ADB using host=%s, port=%d", adbHost, adbPort);
        manager.setTimeout(10, TimeUnit.SECONDS);
        // Wireless debugging can select a different port when it is re-enabled.
        manager.disconnect();
        if (!manager.connect(adbHost, adbPort)) {
            throw new IOException("Could not connect to ADB.");
        }
        Log.d(TAG, "Opening ADB shell...");
        return manager.openStream("shell:");
    }

    @WorkerThread
    static void executeAdbCommand(@NonNull InputStream inputStream,
                                  @NonNull OutputStream outputStream,
                                  @NonNull String command,
                                  @NonNull String successPrefix,
                                  long timeout,
                                  @NonNull TimeUnit timeoutUnit) throws IOException, InterruptedException {
        CountDownLatch commandWatcher = new CountDownLatch(1);
        AtomicBoolean commandSucceeded = new AtomicBoolean(false);
        AtomicReference<Throwable> readFailure = new AtomicReference<>();
        Thread outputThread = new Thread(() -> {
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
                String response;

View on GitHub (pinned to 0152f468fc)