MuntashirAkon/AppManager · error · android.os.RemoteException
Root service did not start as root.
Error message
Root service did not start as root.
What it means
During initLocked in root mode, Ops binds the local root service and then verifies it is actually running as root (LocalServices.alive() and effective UID == ROOT_UID). If the service is not alive or is not running as root, a RemoteException is thrown because privileged operations cannot proceed.
Solutions
- Confirm root actually works: run 'su -c id' via a terminal and verify uid=0
- Re-grant root permission to AppManager in Magisk/SuperSU settings
- Retry init — transient su daemon issues can fail the first bind
- Check SELinux status (setenforce) and Magisk logs for denials; consider enforcing-mode exceptions
Example fix
// before
if (!LocalServices.alive() || Users.getSelfOrRemoteUid() != ROOT_UID) {
throw new RemoteException("Root service did not start as root.");
}
// after
if (!LocalServices.alive()) {
throw new RemoteException("Root service failed to bind; su may be denied.");
}
if (Users.getSelfOrRemoteUid() != ROOT_UID) {
throw new RemoteException("Root service is running as non-root uid=" + Users.getSelfOrRemoteUid());
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!ShellUtils.rootAccess()) { // e.g. test 'su -c id' returns uid=0
// switch to MODE_ADB instead of MODE_ROOT
} Try / catch
try {
Ops.init(...);
} catch (RemoteException e) {
Log.e(TAG, "Root service not running as root; falling back to ADB mode", e);
Ops.setMode(Ops.MODE_ADB);
Ops.init(...);
} Prevention
- Verify su access (test command returning uid 0) before selecting root mode
- Ensure the app is granted superuser in Magisk/KernelSU manager
- Check SELinux policy for denials against the service
- Handle the case where the user denies the superuser prompt
When it happens
Trigger: Selecting root mode and calling Ops.init(...) when the root service fails to bind or the su session drops privileges, e.g. su denies the request or dies immediately after spawn.
Common situations: Device not actually rooted, Magisk superuser prompt denied or timed out, a root manager that breaks Unix socket inheritance, or SELinux preventing the service from keeping root UID.
Related errors
- Current su does not allow Binder communication.
- Failed to access properties of the KeyStore folder.
- Failed to restore ownership info for index
- ADB command did not produce
- ADB daemon not running.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/2edfe04de36c65a7.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/settings/Ops.java:340
LocalServices.stopServices();
}
try {
switch (mode) {
case MODE_ROOT:
if (!sDirectRoot) {
throw new Exception("Root is unavailable.");
}
// Disable remote server first
ExUtils.exceptionAsIgnored(() -> {
if (LocalServer.checkServerHealth(context)) {
LocalServer.getInstance().closeBgServer();
}
});
sIsSystem = sIsAdb = false;
sIsRoot = true;
LocalServices.bindServicesIfNotAlready();
if (!LocalServices.alive() || Users.getSelfOrRemoteUid() != ROOT_UID) {
throw new RemoteException("Root service did not start as root.");
}
return initPermissionsWithSuccess();
case MODE_ADB_WIFI:
sDirectRoot = false;
sIsRoot = sIsSystem = false;
sIsAdb = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (!AdbUtils.isWifiConnected(context)) {
throw new Exception("Wifi not enabled.");
}
if (AdbUtils.enableWirelessDebugging(context)) {
// Wireless debugging enabled, try auto-connect
return STATUS_AUTO_CONNECT_WIRELESS_DEBUGGING;
} else {
// Wireless debugging is turned off or there's no permission
return STATUS_WIRELESS_DEBUGGING_CHOOSER_REQUIRED;
}
} // else fallback to ADB over TCPView on GitHub (pinned to 0152f468fc)