Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français

Manage packages with Pacman

By updated

Improve this page

Pacman is the package manager of Arch Linux and its derivatives (Manjaro, EndeavourOS). This page gives you the commands really useful day to day: install, search, update, remove, clean the cache, configure the repositories and get a stuck system back on its feet. Above all, it insists on the rule that makes the difference between a stable Arch machine and a broken one: a partial upgrade is not supported. It is written for an administrator who already knows apt or dnf and has to operate an Arch machine.

What you will learn

  • Install, search for and inspect a package with Pacman's basic commands.
  • Update the whole system with pacman -Syu, and understand why it is the only supported update operation.
  • Check pending updates without touching the databases.
  • Remove a package, the dependencies it no longer needs and the orphans, without breaking the local database.
  • Configure /etc/pacman.conf: official repositories, custom repository, GPG signatures.
  • Diagnose a file conflict, a locked database or a signature error.

The commands on this page were checked on Arch Linux with Pacman 7.1.0 (libalpm 16.0.1), last recorded on 30 September 2026.

Prerequisites

Pacman needs no installation: it is present from the start on every Arch machine. What you need is a disposable machine to test without risk, because several manipulations described here (partial upgrade, overwriting files) leave lasting traces on a production system.

The rule above all others: no partial upgrade

Arch Linux is a rolling release distribution: there is no frozen version, the repository packages are rebuilt continuously against each other. A package published today is linked against the shared libraries as they exist today in the repositories, not as they exist on your disk. That is why partial upgrades are not supported by the Arch project.

In practice, a partial upgrade happens as soon as you refresh the databases (-y) without updating the whole system (-u). The two classic forms are sudo pacman -Sy package_name and sudo pacman -Sy followed by a plain installation. Pacman then installs the latest version of the requested package and its dependencies, while leaving the rest of the system on older versions. The result: binaries asking for a missing library (error while loading shared libraries), and sometimes a system that no longer boots.

The effect is easy to measure. On a machine whose databases are fresh but whose system lags behind, a pacman -S gcc alone wants to install gcc in version 16.1.1...-3 and its associated libraries, while the already installed gcc-libs package stays at 16.1.1...-1: the system ends up with two generations of libraries meant to work together.

The only supported update operation is therefore the full upgrade:

Terminal window
sudo pacman -Syu

Want to know what awaits you before running the update? Do not use pacman -Sy for that: this command leaves the databases out of sync with the system, which is precisely the situation to avoid. The safe command is checkupdates, provided by the pacman-contrib package: it works on a temporary copy of the database and changes nothing.

Terminal window
sudo pacman -S --needed pacman-contrib
checkupdates

The output lists the packages concerned, old version then new one:

archlinux-keyring 20260612-1 -> 20260707.1-1
libffi 3.6.0-1 -> 3.7.1-1

If no update is available, checkupdates prints nothing and returns a non-zero exit code: it is normal behaviour, handy in a monitoring script.

Install, search for and inspect a package

Read commands (-Ss, -Si, -Q) need no privileges: run them with your normal account. Only the commands that change the system (-S, -R, -U) require sudo, since they write to the local database and to system directories.

Start by looking for the exact package name, then look at what it ships before installing it. The -S operation means sync: it synchronises your machine with the state of the repositories.

Terminal window
pacman -Ss '^htop$'
pacman -Si htop

The -Ss search queries the repository databases and accepts a regular expression, hence the ^ and $ anchors to remove the noise. The output shows the source repository:

extra/htop 3.5.3-1
Interactive process viewer

Installation follows, with the --needed option that avoids reinstalling a package already up to date:

Terminal window
sudo pacman -S --needed htop

Verification: the package is registered in the local database and its binary belongs to it.

Terminal window
pacman -Qi htop | head -3
pacman -Qo /usr/bin/htop

The second command must answer /usr/bin/htop is owned by htop 3.5.3-1. The letter -Q (query) always queries what is installed on the machine, whereas -S queries the remote repositories: it is the most useful distinction to remember in the whole Pacman syntax.

To install an already downloaded package file (a .pkg.tar.zst archive built locally or taken from the cache), use the -U (upgrade) operation:

Terminal window
sudo pacman -U /var/cache/pacman/pkg/htop-3.5.3-1-x86_64.pkg.tar.zst

It is also the command that lets you go back to an older version of a package when the cache still holds it, in case of a regression after an update.

Update the system

sudo pacman -Syu is the central command of Arch maintenance. It chains three things: -y downloads fresh databases from the mirrors, -u compares the state of the repositories with the state of the machine, -S applies the synchronisation. It is the functional equivalent of apt update && apt full-upgrade on Debian, in a single invocation.

Terminal window
sudo pacman -Syu

Verification: run the command again. The second run must answer there is nothing to do, which confirms the machine is aligned with the repositories.

Before an update on an important machine, take thirty seconds to read the Arch project news. It is the channel where the required manual interventions are published: package replacement, configuration format change, renamed repository. An update that breaks without warning almost always has a matching announcement nobody read.

Two options usefully complete the command. -w (downloadonly) downloads the packages without installing them, which lets you prepare a long update while the machine is still available, then apply it in a short window:

Terminal window
sudo pacman -Syuw
sudo pacman -Su

When -Syy is legitimate, and when it is not

The double -yy forces a full re-download of the databases, even if Pacman considers them up to date. It is useful in a single case: you just changed mirror or rewrote /etc/pacman.d/mirrorlist, and you want to start again from the metadata of the new server.

Terminal window
sudo pacman -Syyu

Note that the -u stays: you force the refresh and update the whole system. On the other hand, sudo pacman -Syy alone repairs nothing: it consumes bandwidth, loads the mirrors for no reason, and above all it leaves the machine with databases more recent than the system, which is exactly the entry point of the partial upgrade. It is neither a cure for a corrupted database nor a troubleshooting reflex.

Pick fast mirrors

Pacman's speed depends first on the quality of the mirrors listed in /etc/pacman.d/mirrorlist. The reflector tool queries the status of the official mirrors, filters those that are up to date and sorts them by measured throughput:

Terminal window
sudo pacman -S --needed reflector
sudo reflector --country France --age 12 --protocol https --sort rate --number 10 --save /etc/pacman.d/mirrorlist

The --age 12 option discards mirrors synchronised more than twelve hours ago, --protocol https enforces encrypted transport. After rewriting the list, follow up with sudo pacman -Syyu: it is the legitimate use case of the double -y.

Remove packages and clean up the system

Removal follows the same logic of stacked letters: -R removes the requested package, -s adds its dependencies that are no longer needed, -n also removes the configuration files Pacman would otherwise have saved as .pacsave.

Terminal window
sudo pacman -R htop
sudo pacman -Rs htop
sudo pacman -Rns htop

The choice between the three is not cosmetic. -R alone leaves behind orphan dependencies that pile up. -Rns is the cleanest form for software you want no trace of, but it erases your configuration: if you plan to reinstall later, stay with -Rs and keep the .pacsave.

Verification: pacman -Q htop must answer error: package 'htop' was not found.

Track down orphans

A package is orphan when it was installed as a dependency (-d) and nothing requires it any more (-t, unrequired). The two filters combine on a local query:

Terminal window
pacman -Qdt

If the list is empty, the command prints nothing and returns an exit code of 1: the machine is clean. Otherwise, the -q (quiet) form only returns the names, which lets you pass them to the removal:

Terminal window
sudo pacman -Rns $(pacman -Qdtq)

Clean the cache

Pacman keeps every downloaded package in /var/cache/pacman/pkg/ (the cache directory of the .pkg.tar.zst archives). It is precious insurance: it is from there that you take an older version back with pacman -U after a regression. But the directory grows indefinitely, up to several tens of gigabytes on an old machine.

The -Sc operation removes from the cache the packages that are no longer installed, as well as unused repository databases. It asks for confirmation before acting:

Terminal window
sudo pacman -Sc
Cache directory: /var/cache/pacman/pkg/
:: Do you want to remove all other packages from cache? [Y/n]

The -Scc variant empties everything, including the archives of the packages currently installed: you then lose any possibility of offline rollback. Keep it for machines with critical disk space.

The finer approach goes through paccache, also provided by pacman-contrib. It keeps the last three versions of each package by default:

Terminal window
sudo pacman -S --needed pacman-contrib
sudo paccache -r

The -k option sets the number of versions kept: sudo paccache -rk1 keeps only one, sudo paccache -r -k0 empties the cache. Add -d (dryrun) to see what would be removed without erasing anything. The output announces the result, for instance ==> finished: 1 packages removed (disk space saved: 49.91 KiB).

Back up the package list

Before a heavy intervention, or simply to prepare a reinstallation, export the list of packages installed explicitly (as opposed to those pulled in as dependencies):

Terminal window
pacman -Qqe > /root/installed-packages.txt

Restoring is done by feeding this file back on standard input: the - dash asks Pacman to read its targets from stdin, and --needed avoids reinstalling what is already in place.

Terminal window
sudo pacman -S --needed - < /root/installed-packages.txt

This backup is an inventory, not an image of the system: it holds neither your configurations in /etc nor your data. It combines with a regular backup, it does not replace it.

Configure Pacman with /etc/pacman.conf

The /etc/pacman.conf file (Pacman's global configuration) holds an [options] block then the ordered list of repositories. The order matters: for an identical package name, the first declared repository wins, whatever the version.

Terminal window
sudo nano /etc/pacman.conf

On an up-to-date Arch, the official repositories enabled by default are [core] (the foundation: kernel, pacman, glibc, systemd) and [extra] (all the rest of the officially packaged software). Two other repositories are present but commented out: [multilib], to enable for 32-bit libraries (Steam, Wine), and the *-testing repositories, reserved for packages in preparation.

Comfort options

Under [options], a few settings change daily life. They go on one line each, with no value for the first three:

[options]
Color
VerbosePkgLists
ParallelDownloads = 5
ILoveCandy

Color colours the output, which makes conflicts and warnings immediately visible. VerbosePkgLists shows updates as a table with the old and new version: it is what lets you spot at a glance that a critical library changes major version. ParallelDownloads sets the number of simultaneous downloads. ILoveCandy replaces the progress bar with a nod to Pac-Man, with no technical effect.

Verification: a simple sudo pacman -Sy must run without any syntax error message, with the output now coloured.

Add a custom repository

A home-made repository (internal company packages, a project mirror) is declared at the end of the file, hence after the official repositories so as not to supersede them:

[internal-repo]
SigLevel = Required DatabaseOptional
Server = https://packages.example.internal/arch/$arch

The SigLevel line is the security point. Required enforces that every package is signed by a key your machine recognises. You will often come across SigLevel = Optional TrustAll in tutorials: this value effectively disables the check and trusts any signature, including that of an attacker able to sit between your machine and the server. Do not use it on a production machine.

For a signed repository to work, import its public key into Pacman's keyring, then sign it locally to mark it as trusted:

Terminal window
sudo pacman-key --recv-keys <key-fingerprint>
sudo pacman-key --lsign-key <key-fingerprint>

Verification: sudo pacman -Sy must refresh the new repository without raising a signature error, and pacman -Sl internal-repo must list its packages.

Troubleshoot common errors

Pacman failures look alike from one machine to another. The table below gives the entry point; the following sections detail the two cases where a wrong move makes the situation lastingly worse.

SymptomLikely causeCorrective action
failed to init transaction (unable to lock database)A Pacman is already running, or a previous one was killedCheck with ps aux | grep pacman, then sudo rm /var/lib/pacman/db.lck if no process
exists in filesystemA file on disk belongs to no packageIdentify it with pacman -Qo, then a targeted --overwrite (see below)
invalid or corrupted package (PGP signature)Outdated keyringsudo pacman -S archlinux-keyring then rerun sudo pacman -Syu
error while loading shared libraries after an installationPartial upgradeA full sudo pacman -Syu right away
package 'name' was not found although it is installedEntry missing from the local databaseRemove nothing, see the section on the local database

The /var/log/pacman.log file (the log of every transaction) remains the best source when the terminal output is not enough: it timestamps every installation, update and removal, and lets you reconstruct what preceded the failure.

Terminal window
sudo less /var/log/pacman.log

The db.lck lock

Pacman creates /var/lib/pacman/db.lck at the start of a transaction to prevent two instances from writing at the same time. If the process is abruptly interrupted (power cut, terminal closed), the file survives and blocks every following operation:

error: failed to init transaction (unable to lock database)
error: could not lock database: File exists

Before removing the lock, make sure no Pacman is really running (a graphical update in the background, for instance). Removing the lock of an active transaction corrupts the database.

Terminal window
ps aux | grep -c '[p]acman'
sudo rm /var/lib/pacman/db.lck

The exists in filesystem file conflict

It is the most frequent error. It occurs when Pacman wants to write a file that already exists without belonging to the package it is installing:

error: failed to commit transaction (conflicting files)
tree: /usr/bin/tree exists in filesystem

The first step is to find out who owns this file:

Terminal window
pacman -Qo /usr/bin/tree

Two possible answers. If another installed package claims it, you have a real conflict between packages: force nothing, it is a repository problem or a badly built AUR package, to solve by removing the faulty package. If the answer is error: No package owns /usr/bin/tree, the file was dropped by hand or left by an incomplete removal: it is legitimate to let Pacman replace it, by explicitly naming the path concerned.

Terminal window
sudo pacman -S --overwrite /usr/bin/tree tree

Pacman's local database is not repaired with rm

/var/lib/pacman/local/ holds one directory per installed package: it is the inventory of the machine, the list of files laid down by each package and their checksums. Many tutorials suggest removing an entry deemed "corrupted" with an rm. It is a very bad idea, and the demonstration is immediate.

After removing the tree directory from the local database, Pacman purely and simply forgets the package exists, while its files are still on disk:

$ pacman -Q tree
error: package 'tree' was not found

Reinstalling then runs into the orphan files it no longer recognises, and the system enters the conflict loop described above:

error: failed to commit transaction (conflicting files)
tree: /usr/bin/tree exists in filesystem

You are now forced to overwrite to repair damage you caused yourself. The right approach, when you suspect the database or the files of a package, is to check before acting. The -Qkk operation compares the installed files with what the database expects (size, permissions, owner):

Terminal window
pacman -Qkk tree

The output tree: 16 total files, 0 altered files means everything is compliant. If files are altered, reinstall cleanly with sudo pacman -S tree. And if a database entry is really unreadable, restore /var/lib/pacman/local/ from a backup or a system snapshot, relying on /var/log/pacman.log to know which packages were in place. You do not rebuild an inventory with rm.

Use the AUR without putting yourself at risk

The AUR (Arch User Repository) is Arch's community repository. It holds no binary packages but PKGBUILDs: scripts that describe how to download the sources and build the package on your machine. It is what gives access to software missing from the official repositories, but it is also what changes the nature of the risk: you run code written by a stranger, with your rights.

Two reflexes make the AUR usable with peace of mind. First, read the PKGBUILD before every build, in particular the source URLs and the content of the prepare() and build() functions. Then, never run makepkg as root: makepkg actually refuses to start as root, precisely because a malicious script would have every right there.

AUR packages being in no repository, they show up as foreign to the sync database. This is how you list them:

Terminal window
pacman -Qm

Build a package by hand

The reference path uses no third-party tool: you clone the package's Git repository, you inspect the PKGBUILD, then you build. The build tools are gathered in the base-devel group.

Terminal window
sudo pacman -S --needed git base-devel
git clone https://aur.archlinux.org/yay.git
cd yay
less PKGBUILD
makepkg -si

The -s option of makepkg installs the missing build dependencies, -i installs the produced package at the end through pacman -U. An AUR helper such as yay or paru then automates this cycle, but it does not spare you the review: yay -S package_name builds third-party code exactly like makepkg.

Verification: pacman -Qm must now list yay with its version.

Write a correct PKGBUILD

A minimal PKGBUILD declares the name, the version, the architecture, the sources, and the build functions and packaging functions. Above all, it declares an array of checksums: without it, makepkg refuses to work.

Terminal window
pkgname=myinternaltool
pkgver=1.0
pkgrel=1
pkgdesc="Internal monitoring tool"
arch=('any')
license=('MIT')
source=("myinternaltool-$pkgver.tar.gz")
sha256sums=('e239672bbca007c25a020d5e62fd7949fcb80f307ba98eab9df692aeea3e02bd')
package() {
cd "$srcdir/$pkgname-$pkgver"
install -Dm755 myinternaltool "$pkgdir/usr/bin/myinternaltool"
}

The checksum above is that of the archive used for the example: yours will differ, and you never copy it by hand. Without this sha256sums line, the build stops dead, whatever the quality of the rest of the script:

==> ERROR: Integrity checks are missing for: source

It is not a formality: these checksums guarantee that the downloaded archive is the one the maintainer tested, and not a version substituted on the way. You do not write them by hand: the updpkgsums command (pacman-contrib package) computes the checksums of the declared sources and injects them into the PKGBUILD.

Terminal window
updpkgsums
makepkg -si

Verification: grep sha256sums PKGBUILD must show the filled array, and makepkg must end on ==> Finished making: myinternaltool 1.0-1.

Key points

  • Partial upgrades are not supported on Arch. The only update operation is the full sudo pacman -Syu. pacman -Sy package_name and "updating a single package" break the shared libraries.
  • To know the pending updates without desynchronising the machine, use checkupdates (pacman-contrib package), never pacman -Sy.
  • -S queries the repositories, -Q queries the installed packages, -R removes, -U installs a local file. All the rest is just stacked letters.
  • -Syy is only justified after a mirror change, and always followed by -u (pacman -Syyu). It is not a troubleshooting tool.
  • The [community] repository no longer exists: it has been merged into [extra] since May 2023. The default repositories are [core] and [extra], plus [multilib] if you need 32-bit.
  • On an exists in filesystem conflict, identify the owner with pacman -Qo then use --overwrite on a precise path. The --overwrite '*' glob overwrites files belonging to other packages and makes the local database lie.
  • Never remove an entry from /var/lib/pacman/local/: Pacman loses track of the package, its files stay on disk and any reinstallation runs into conflicts. Check with pacman -Qkk, restore from a backup.
  • Clean with paccache -r (three versions kept) rather than with -Scc, and remove orphans with pacman -Rns $(pacman -Qdtq) after checking that pacman -Qdt really returns something.
  • The AUR builds third-party code on your machine: read the PKGBUILD, never run makepkg as root, and always declare a sha256sums array in your own packages.

Knowledge check

Check that the essentials of this guide are acquired. The questions only cover what has just been explained here.

Knowledge check

Check what you have learned with this interactive quiz

6 questions
6 min
70% to pass

How it works

  • The timer starts when you click Start
  • Multiple choice, true/false and short answer questions
  • You can move between questions
  • Detailed results are shown at the end

Starts the quiz and the timer

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn