This error occurs when apt cannot mark a package as manually installed, typically because the package is virtual, not installed, or has dependency issues. Virtual packages are references to other packages and cannot be directly marked as manually installed.
The "E: Cannot mark package as manually installed" error means that apt's `apt-mark manual` command cannot mark the specified package as manually installed. This happens for several reasons: When you install a package manually (explicitly requesting it), apt marks it as "manually installed" to protect it from being automatically removed when it's no longer a dependency of other packages. Conversely, packages installed as dependencies are marked as "automatically installed" and can be removed by `apt autoremove` if nothing needs them. The error occurs when apt cannot perform this marking operation, usually because the target is a virtual package (which doesn't have a physical installation), the package isn't actually installed, or dependency resolution prevents the marking.
First, check if the package is truly installed on your system:
dpkg -l | grep package-nameor more specifically:
dpkg -l | grep '^ii' | grep package-nameThe output should show lines starting with ii (installed). If you see nothing, the package is not installed. You cannot mark a non-installed package as manually installed.
If the package is not installed, install it first:
sudo apt install package-nameThen try marking it:
sudo apt-mark manual package-nameVirtual packages are references to other packages and cannot be directly marked. Check if your package is virtual:
apt-cache show package-name | grep -E '^(Package|Virtual):'If the output shows "Virtual: yes" or "Provides:", the package is virtual. Virtual packages are typically metapackages like:
- java-runtime (virtual, provided by openjdk-11-jre, openjdk-17-jre, etc.)
- python (virtual, provided by specific Python versions)
- mailserver (virtual, provided by postfix, sendmail, etc.)
Solution for virtual packages: Mark the real package that provides it instead:
# Find what provides the virtual package
apt-cache depends --recurse package-name
# Then mark the concrete package:
sudo apt-mark manual openjdk-11-jreOr use apt-cache rdepends to see reverse dependencies:
apt-cache rdepends package-nameA corrupted or out-of-sync APT cache can cause marking issues. Refresh it:
sudo apt updateThen try marking the package again:
sudo apt-mark manual package-nameIf that still fails, you can clean the cache and rebuild it:
sudo apt clean
sudo apt updateThe apt clean command removes cached package files (you can safely delete these), while apt update refreshes the package list from repositories.
Get detailed information about the package's installation state:
apt-cache policy package-nameThis shows:
- Candidate version (what would be installed)
- Installed version (what's actually on your system)
- Available versions from repositories
Also check if it's marked as on-hold:
apt-mark showholdIf your package is in the hold list, it might prevent marking:
sudo apt-mark unhold package-name
sudo apt-mark manual package-nameIf the package has unmet dependencies, apt may refuse to mark it. Check for issues:
sudo apt --fix-broken installThis command tries to fix dependency issues without making changes:
sudo apt checkIf there are broken dependencies, fix them first before marking:
# Show what depends on this package
apt-cache rdepends package-name
# Show what this package depends on
apt-cache depends package-name
# Try to fix dependency issues
sudo apt --fix-broken installAfter resolving dependencies, try marking again:
sudo apt-mark manual package-namePackage names are case-sensitive and may differ from what you expect. Find the exact name:
apt search patternFor example:
# Wrong: trying to mark 'Java'
sudo apt-mark manual Java
# Error: Package not found
# Correct: use the actual package name
apt search java-runtime
sudo apt-mark manual default-jreCommon package name confusions:
- node vs nodejs (Node.js)
- python vs python3 vs python3.10 (specific Python version)
- java vs default-jre vs openjdk-11-jre (Java runtime)
- docker vs docker.io (Docker)
Always use:
apt-cache show package-nameto confirm the package exists before trying to mark it.
Sometimes resetting the marking state helps resolve conflicts. Try this sequence:
# Check current state
apt-mark showmanual | grep package-name
# Try marking as auto first
sudo apt-mark auto package-name
# Then mark as manual
sudo apt-mark manual package-nameIf the package is already in the manual list, this refresh can clear any state issues.
You can also view all manually and automatically installed packages:
# Show all manually installed packages
apt-mark showmanual
# Show all automatically installed packages
apt-mark showauto
# Count them
apt-mark showmanual | wc -l
apt-mark showauto | wc -lUnderstanding APT's marking system: The status of packages is tracked in the APT database (/var/lib/apt/extended_status). When you mark a package as manual, you're telling APT that this package was explicitly requested by the user, not pulled in as a dependency. This status survives upgrades and is crucial for apt autoremove to work correctly.
Virtual packages in depth: Virtual packages are declared in the Provides field of actual packages. For example:
# java-runtime is virtual, provided by many concrete packages:
apt-cache search java-runtime
# Shows providers like: default-jre, openjdk-11-jre, openjdk-17-jre, etc.Virtual packages are useful for dependencies that don't care which implementation is used, but they cannot be installed or marked directly.
Metapackages: Some packages (often ending in -meta) are metapackages that exist only to bring in other packages. These can be marked but are lightweight wrappers:
apt-cache show ubuntu-desktop
# This is a metapackage that depends on many GUI packagesDependency resolution order: When APT installs a package, it marks:
- The explicitly requested package: manual
- All dependencies pulled in: auto
If you later explicitly install a package that was previously auto, apt automatically marks it as manual.
Checking mark status programmatically: You can query the APT database directly:
# Dump extended status
grep -E '^(Package|Auto-Installed):' /var/lib/apt/extended_status | paste - - | grep package-nameAPT cache clearing: If you suspect corruption:
# Dangerous: removes all cached data
sudo rm -rf /var/lib/apt/extended_status
sudo apt update
# Or more safely, use:
sudo apt clean
sudo apt updateE: Could not connect to proxy server
Could not connect to proxy server
E: Package 'package:i386' has no installation candidate
How to fix "Package package:i386 has no installation candidate" in apt
E: The value 'value' is invalid for APT::Default-Release
How to fix invalid APT::Default-Release value in APT
dpkg: error: unable to create new file 'path': Permission denied
How to fix dpkg permission denied errors in APT
subprocess installed post-removal script returned error exit status 1
How to fix "subprocess installed post-removal script returned error exit status 1" in APT