pm uninstall
destructiveRemoves a package, or removes it for one Android user only — which is how a preinstalled app is disposed of without root.
- Command
- adb shell pm uninstall
- Commands
- Packages (pm)
- Risk
- destructive
Syntax
pm uninstall [-k] [--user <id>] <package>Flags and arguments
| Token | Meaning |
|---|---|
| -k | Keep the app's data and cache directories. This is what makes the removal reversible. |
| --user <id> | Remove for one Android user. For a preinstalled app this is the only form that works without root: the APK stays in the system image and the app simply stops existing for that user. |
Examples
pm uninstall com.exampleRemove a sideloaded app completely, data included.
pm uninstall -k --user 0 com.manufacturer.bloatRemove a preinstalled app for the primary user, keeping its data so it can be restored.
cmd package install-existing --user 0 com.manufacturer.bloatThe antidote to the previous line: reinstate the app for that user.
Reading the output
Sample output
SuccessOne word. `Success` is the whole success message; a failure is `Failure [<reason>]`, and the reason inside the brackets is the useful part — `DELETE_FAILED_INTERNAL_ERROR`, or `Failure [not installed for 0]` when the app was already gone for that user. Read the state back with `pm list packages -u` afterwards rather than trusting the line alone.
Output fields
| Field | Meaning |
|---|---|
| Success | The package was removed for the user asked about. |
| Failure [<reason>] | Nothing was removed. The bracketed reason is the platform's own code. |
| Failure [not installed for 0] | The package was already absent for that user — often the answer, not an error. |
What access it needs
An authorised `adb` connection and nothing more, provided you stay on the `--user` form. Removing a preinstalled app for one Android user needs no root precisely because nothing leaves the system image: the APK stays where the vendor put it and the package merely stops existing for that user, which is what makes `cmd package install-existing --user 0 <pkg>` able to put it back afterwards. Asking instead to remove a package that lives on the read-only system partition outright is the case privileges would be needed for, and it is refused rather than half-done. No developer-options toggle unlocks any of this, and `adb root` is unavailable on a production build, so a refusal is a signal to change the command rather than to hunt for a switch. Which manifest permission the platform checks for the deletion itself is not verified in this repository; what is verified is the shape of the answer, which is why the Android Debloat Tool re-reads the package list afterwards instead of believing one line.
Failure messages, decoded
| Message | Meaning |
|---|---|
| Failure [DELETE_FAILED_INTERNAL_ERROR] | The package manager refused the deletion and offered no further detail. `runUninstall` passes the bracketed reason through untouched, so this is the platform's own word rather than an interpretation of it. The first thing to rule out is a package on the read-only system image addressed without `--user`; this repository has not confirmed on hardware which conditions map to which bracketed reasons. |
| Failure [not installed for 0] | Nothing was removed because the package was already absent for that user. Frequently the answer rather than an error — it is what a second run of a removal that already worked prints. Settle it by re-reading `pm list packages -u`, which still lists anything removed with `-k`. |
| Exception occurred while executing 'uninstall': | The wrapper caught a `Throwable`; the next line names it. `classifyPmUninstall` treats any such banner as a failure even when a `Success` line appears beside it, because a run that printed both is not a run to report success for. |
What it changes, and the way back
`pm uninstall --user 0 <pkg>` removes the app for that user. With `-k` its data is kept and `cmd package install-existing --user 0 <pkg>` puts the app back; without `-k` the data is gone and only a reinstall from an APK restores the app. Removing a system component this way can leave the phone unable to boot past setup, and a factory reset is then the only cure — so decide per package, never in bulk.
Version and vendor notes
- After a `-k` removal the package appears in `pm list packages -u` but not in the default list. That difference is the only reliable way to find what can be restored.
- An OEM that reworded the success line makes a correct removal look failed. Re-reading the package list is what settles it.
We have a UI for this
Android Debloat Tool runs this command over USB and parses what comes back — a Chromium browser, no SDK, nothing uploaded.
Related commands
Commands that turn up in the same session as pm uninstall.
| Command | What it does |
|---|---|
| pm list packages | Lists installed packages, optionally with the APK path, uid, version code and installer. |
| pm disable-user | Switches a package off for one Android user without removing it — the reversible alternative to uninstalling. |
| pm clear | Wipes an app's data — or, on Android 13 and later, only its cache. |
| dumpsys package | Everything the package manager knows about one app: version, paths, flags, install source and per-user state. |
More Packages (pm) commands
| Command | What it does |
|---|---|
| pm path | Prints the absolute paths of the APK files that make up an installed package. |
| pm trim-caches | Asks the system to drop cached files until the given amount of free space exists. |
| pm install | Installs one APK that is already on the device, which is what `adb install` does under the hood. |
| pm install-create | Opens an install session so several APKs — a base plus its splits — are installed as one atomic unit. |
Checked against AOSP, toybox and kernel sources while writing the parsers behind our Web ADB tools. Where a behaviour genuinely varies by Android version or manufacturer, this page says so instead of giving a number that would be wrong on half the phones out there.