MuntashirAkon/AppManager · error · IOException

OpenPGPService could not be bound.

Error message

OpenPGPService could not be bound.

What it means

OpenPGPCrypto binds to the external OpenPGP provider app (e.g. OpenKeychain) via OpenPgpServiceConnection. waitForServiceBound polls up to ~100 seconds; if mService.getService() is still null, binding never succeeded and an IOException is thrown.

Solutions

  1. Install/enable the OpenPGP provider app (e.g. OpenKeychain) matching the provider package name
  2. Verify the provider package passed to OpenPGPCrypto/options is correct (org.sufficientlysecure.keychain for OpenKeychain)
  3. Approve the app's access request in the OpenPGP provider
  4. Retry the operation to give binding more time if the device was slow

Example fix

// before
cryptoOptions.setProvider("com.example.wrongkeychain");
// after
cryptoOptions.setProvider("org.sufficientlysecure.keychain"); // OpenKeychain installed & enabled
Defensive patterns

Strategy: retry

Validate before calling

// ensure the provider app exists before attempting
PackageManager pm = context.getPackageManager();
try {
    pm.getPackageInfo("org.sufficientlysecure.keychain", 0);
} catch (PackageManager.NameNotFoundException e) {
    throw new IllegalStateException("OpenPGP provider (OpenKeychain) is not installed");
}

Try / catch

try {
    crypto.doAction(Crypto.OPEN_ENCRYPT, in, out);
} catch (IOException e) {
    if (e.getMessage().contains("could not be bound")) {
        // retry once, or prompt the user to install/open OpenKeychain
    }
}

Prevention

When it happens

Trigger: Calling handleFiles/handleStreams when the OpenPGP provider app is not installed, the provider package name (mProvider) is wrong, the user denied the bind/connect dialog, or binding didn't complete within the timeout.

Common situations: OpenKeychain not installed on the device; user cancels the authorization prompt for this app; wrong provider package passed to the crypto options; provider app crashed or disabled.

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/998b139fd773bcac. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/crypto/OpenPGPCrypto.java:253

        IntentFilter filter = new IntentFilter(ACTION_OPEN_PGP_INTERACTION_BEGIN);
        filter.addAction(ACTION_OPEN_PGP_INTERACTION_END);
        ContextCompat.registerReceiver(mContext, mReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED);
    }

    @WorkerThread
    private void waitForServiceBound() throws IOException {
        int i = 0;
        while (mService.getService() == null) {
            if (i % 20 == 0) {
                Log.i(TAG, "Waiting for openpgp-api service to be bound");
            }
            SystemClock.sleep(100);
            if (i > 1000)
                break;
            i++;
        }
        if (mService.getService() == null) {
            throw new IOException("OpenPGPService could not be bound.");
        }
    }

    @WorkerThread
    private void waitForResult() {
        int i = 0;
        while (!mSuccessFlag && !mErrorFlag) {
            if (i % 200 == 0) Log.i(TAG, "Waiting for user interaction");
            SystemClock.sleep(100);
            if (i > 1000)
                break;
            i++;
        }
    }

    @UiThread
    private void handleResult(@NonNull Intent result) {
        mSuccessFlag = false;

View on GitHub (pinned to 0152f468fc)