apt-cache

Search and inspect packages without installing them

Updated 2026-08-26

apt-cache answers questions about packages without changing any of them. Everything it knows came out of the last apt update, so its queries need neither the network nor root. Most of what it can describe is software this machine has never had.

Which version you would get

apt-cache policy <package> prints what is installed now and what apt install would fetch. If those two lines differ, an upgrade is available and nobody has applied it. A candidate of (none) means apt has the name and no version to go with it, which is the failure behind "Package has no installation candidate".

Under them comes the version table, one line per version apt can see. Each carries the priority that ranked it and the repository it came from, and the entry at priority 100 pointing to /var/lib/dpkg/status is whatever is installed. Read the table when a machine is being offered something you did not expect. The answer is usually a repository someone added, and third-party repositories covers pinning one back down.

What the cache holds, and when it was filled

apt update fetches the repository indexes into /var/lib/apt/lists/, and apt compiles those into the index apt-cache reads. Nothing here goes near the network, so the answers are as old as that update: a package apt-cache claims not to know about is usually a machine that has not run apt update since the archive moved.

Describing a package is not evidence of having it. apt-cache show will print the full record for something dpkg -s has never heard of.

apt-cache or apt

apt search and apt show are the same queries with the output laid out for reading, and at a prompt they are usually what you want. apt-cache is the one to call from a script, for the reason apt vs apt-get goes into: apt's command-line interface is not stable between versions, so it shouldn't be relied upon in a script. It will print a warning to remind you.

What it cannot tell you

dpkg -S names the package a file on disk came from, out of what dpkg recorded when it unpacked it. That only reaches packages you have installed. For a file you do not have yet, apt-file search answers the same question, and the command is not installed by default. Installing the apt-file package also adds the archive's Contents index to what apt update fetches, so the sequence is install, update, then search.

Sample files used on this page

Every example below was run against these files. Recreate them to follow along.

/etc/apt/sources.list.d/vendor.sources the sandbox has a second repository configured alongside Debian's, which is what the version tables below are reading. It carries two packages: hello-tips, which Debian does not have at all, and a bash-completion at version 1:99.0-1, higher than the one Debian ships. Trusted: yes is there because this one is unsigned and local; a repository reached over the network wants Signed-By instead, which third-party repositories covers.

Types: deb
URIs: file:/srv/vendor
Suites: stable
Components: main
Trusted: yes

which of the page's packages are installed

ii  bash-completion 1:2.16.0-7
ii  cowsay 3.03+dfsg2-8
51 outputs, collapsed by default

Which version would I get

apt-cache policy answers that whenever a package is not the version you expected. Installed is what is on the machine now and Candidate is what apt install would fetch, and the two lines together answer most of the question on their own.

Check what is installed and what apt would install

apt-cache policy cowsay | head -3

The two lines agreeing means the machine already has the version apt would choose, so there is nothing to upgrade. No root and no network: this reads the cache apt update last filled.

Show output
cowsay:
  Installed: 3.03+dfsg2-8
  Candidate: 3.03+dfsg2-8

See which version you would get before installing

apt-cache policy cowsay-off | head -3

(none) in the Installed line means the package is not on the machine. The Candidate line is what would arrive if you ran apt install cowsay-off, which is worth knowing before you agree to it.

Show output
cowsay-off:
  Installed: (none)
  Candidate: 3.03+dfsg2-8

Find out whether an upgrade is waiting

apt-cache policy bash-completion | head -3

The two lines disagreeing means an upgrade is available and not yet applied. Here the candidate comes from a repository other than Debian's, which the version table below these lines spells out.

Show output
bash-completion:
  Installed: 1:2.16.0-7
  Candidate: 1:99.0-1

Read the whole version table

apt-cache policy hello-tips

Under the first two lines, one entry per version apt can see. Each is followed by its priority, which is what decides the winner, and the indented line beneath names the repository the version came from.

Show output
hello-tips:
  Installed: (none)
  Candidate: 1.0-1
  Version table:
     1.0-1 500
        500 file:/srv/vendor stable/main all Packages

Find out which repository a version is coming from

apt-cache policy bash-completion | head -6

The diagnostic to run when a package sits at a version you did not expect. A second repository is offering a higher version than Debian at the same priority, so it wins, and Debian's own entry follows below the six lines shown. See third-party repositories for how to stop that happening.

Show output
bash-completion:
  Installed: 1:2.16.0-7
  Candidate: 1:99.0-1
  Version table:
     1:99.0-1 500
        500 file:/srv/vendor stable/main all Packages

Recognise a package with no installation candidate

apt-cache policy default-mta

A Candidate of (none) and an empty version table means apt knows the name but has no version to offer. Here it is a virtual package, a name real packages claim rather than one of their own. The same output appears when a package has been dropped from the archive.

Show output
default-mta:
  Installed: (none)
  Candidate: (none)
  Version table:

Ask about several packages at once

apt-cache policy cowsay cowsay-off | grep -E '^[a-z]|: '

Every name you pass gets its own stanza. Dropping the version tables with grep fits a whole set of packages into a few lines.

Show output
cowsay:
  Installed: 3.03+dfsg2-8
  Candidate: 3.03+dfsg2-8
cowsay-off:
  Installed: (none)
  Candidate: 3.03+dfsg2-8

Notice that an unknown package name says nothing

apt-cache policy nosuchpackage; echo "exit $?"

No output and a success exit status, which is the trap on this command. A typo in a package name looks exactly like a package apt has nothing to say about, so never take a silent policy as confirmation the name was right.

Show output
exit 0

Pull the candidate version into a variable

V=$(apt-cache policy cowsay-off | awk '/Candidate:/ {print $2}'); echo "would install $V"

The field-per-line format is stable enough to parse, which is what apt-cache is for in a script where apt would print a warning. See Variables and quoting.

Show output
would install 3.03+dfsg2-8

Report whether a package is up to date

apt-cache policy bash-completion | awk '/Installed:/{i=$2} /Candidate:/{c=$2} END{ if (i==c) print "up to date"; else print "upgrade available: " i " -> " c }'

Comparing the two fields as strings, rather than trying to work out which version is newer. apt has already decided that; the candidate is by definition what it would install.

Show output
upgrade available: 1:2.16.0-7 -> 1:99.0-1

List the repositories apt is reading from

apt-cache policy | head -5

With no package named, policy prints the sources themselves and the priority each carries. /var/lib/dpkg/status at 100 is what is already installed, which is why an installed version is never silently replaced by an equal-priority one.

Show output
Package files:
 100 /var/lib/dpkg/status
     release a=now
 500 file:/srv/vendor stable/main all Packages
     release o=ExampleVendor,a=stable,n=stable,c=main,b=all

Show where a version lives and where it came from

apt-cache madison hello-tips

madison is the version table in one line per version, named after the Debian archive tool whose output it imitates. Handy when you want the answer on a single line rather than in a stanza.

Show output
hello-tips |      1.0-1 | file:/srv/vendor stable/main all Packages

Report the candidate version for a list of packages

for pkg in cowsay cowsay-off hello-tips; do printf '%s %s\n' "$pkg" "$(apt-cache policy "$pkg" | awk '/Candidate:/{print $2}')"; done

policy takes several names at once, but a loop keeps each answer on its own line and lets you format it. See Loops.

Show output
cowsay 3.03+dfsg2-8
cowsay-off 3.03+dfsg2-8
hello-tips 1.0-1

Reading a package's record

apt-cache show prints the stanza the repository publishes about a package, which is the same information dpkg -s gives for an installed one. The difference is that this works for packages you have never installed.

Read a package's description and metadata

apt-cache show cowsay | head -8

Everything the archive says about the package, one field per line. apt show prints the same record with the layout rearranged for reading.

Show output
Package: cowsay
Version: 3.03+dfsg2-8
Installed-Size: 92
Maintainer: James McDonald <james@jamesmcdonald.com>
Architecture: all
Depends: libtext-charwidth-perl, perl:any
Suggests: filters, cowsay-off
Description: configurable talking cow

Pick out just the fields you care about

apt-cache show cowsay | grep -E '^(Version|Installed-Size|Depends)'

Installed-Size is in kilobytes and is the archive's estimate of what the package will occupy once unpacked, which is not the size of the download.

Show output
Version: 3.03+dfsg2-8
Installed-Size: 92
Depends: libtext-charwidth-perl, perl:any

See a dependency's version constraints

apt-cache show cowsay-off | grep -E '^(Depends|Breaks|Replaces)'

The version ranges that apt-cache depends leaves out. Breaks and Replaces naming the same package as Depends is how a split package tells apt that older copies must go.

Show output
Replaces: cowsay (<< 3.03+dfsg2-3)
Depends: cowsay (>= 3.03+dfsg2-3)
Breaks: cowsay (<< 3.03+dfsg2-3)

Find the file apt would download

apt-cache show cowsay | grep -E '^(Filename|Size|SHA256)'

The path within the repository, the size of the .deb in bytes, and the checksum apt verifies after fetching it. Filename is relative to the repository's URI.

Show output
Filename: pool/main/c/cowsay/cowsay_3.03+dfsg2-8_all.deb
Size: 21372
SHA256: 5b16f90ff97871aa0f442087abc1878940d00e310f74190ba854a097545204bf

Ask about one specific version

apt-cache show cowsay=3.03+dfsg2-8 | head -3

The name=version form works anywhere apt takes a package name, including apt install. Without it you get the candidate, which may not be the version you are asking about.

Show output
Package: cowsay
Version: 3.03+dfsg2-8
Installed-Size: 92

Notice that show prints every version it knows

apt-cache show bash-completion | grep '^Version:'

A stanza is printed per version rather than per package, so piping apt-cache show into grep can return more lines than you expected on a machine with several repositories configured.

Show output
Version: 1:99.0-1
Version: 1:2.16.0-7

Read the raw record apt keeps

apt-cache showpkg hello-tips

The internal view: which index files list the package, what it depends on, and what depends on it. Denser than show and rarely what you want, but it is the only place that names the index file a version was read from.

Show output
Package: hello-tips
Versions:
1.0-1 (/var/lib/apt/lists/_srv_vendor_dists_stable_main_binary-all_Packages.lz4)
 Description Language:
                 File: /var/lib/apt/lists/_srv_vendor_dists_stable_main_binary-all_Packages.lz4
                  MD5:


Reverse Depends:
Dependencies:
1.0-1 -
Provides:
1.0-1 -
Reverse Provides:

Test whether apt knows a package name at all

apt-cache show nosuchpackage; echo "exit $?"

Unlike policy, show treats an unknown name as an error and says so. That makes it the one to use when a script needs to tell a typo from a package it has nothing to say about.

Show output
E: No packages found
exit 100

Watch a virtual package print nothing

apt-cache show default-mta; echo "exit $?"

A virtual package has no record of its own, so show prints nothing and still succeeds. apt-cache showpkg lists the real packages providing the name, under Reverse Provides.

Show output
exit 0

Read about a package the machine has never had

dpkg -s cowsay-off 2>&1 | head -1; apt-cache show cowsay-off | head -1

dpkg answers from what is installed and apt-cache answers from the archive, so the package dpkg has never heard of is one apt-cache can describe in full.

Show output
dpkg-query: package 'cowsay-off' is not installed and no information is available
Package: cowsay-off

Understand why showsrc has nothing to say

apt-cache showsrc cowsay 2>&1 | head -1

showsrc reads source package records, which come from deb-src lines that a default Debian install does not have. Add one to /etc/apt/sources.list.d/debian.sources and run apt update before expecting an answer.

Show output
E: You must put some 'deb-src' URIs in your sources.list

Finding a package by name or description

apt-cache search takes a regular expression and matches it against both package names and their descriptions, which is why a short search term returns so much. Everything here reads the cache, so a package added to the archive since your last apt update will not appear.

Search for a package

apt-cache search cowsay

Name on the left, short description on the right. The pattern matched all three of these in the name, but it would have matched a package whose description mentioned cowsay too.

Show output
cowsay - configurable talking cow
cowsay-off - configurable talking cow (offensive cows)
xcowsay - Graphical configurable talking cow

Search names only, ignoring descriptions

apt-cache search --names-only '^cow' | sort

--names-only (short form -n) is what narrows a search that has come back as pages of results. Results arrive in cache order rather than alphabetically, so pipe through sort if the order matters.

Show output
cowbuilder - pbuilder running on cowdancer
cowdancer - Copy-on-write directory tree utility
cowpatty - Brute-force WPA dictionary attack
cowsay - configurable talking cow
cowsay-off - configurable talking cow (offensive cows)

Narrow a search with several terms

apt-cache search talking cow

Every pattern given has to match, in any order and anywhere in the record. Adding a term is usually faster than writing a cleverer regex.

Show output
cowsay - configurable talking cow
cowsay-off - configurable talking cow (offensive cows)
xcowsay - Graphical configurable talking cow

Match a package name exactly

apt-cache search --names-only '^cowsay$'

The pattern is a regular expression, so ^ and $ anchor it to the whole name. Without the anchors this would also match cowsay-off and xcowsay.

Show output
cowsay - configurable talking cow

Read the full record for each result

apt-cache search --full cowsay-off | head -6

--full swaps the one-line summary for the same record apt-cache show prints. Useful for searching and inspecting in one pass, and long enough that it usually wants a pipe.

Show output
Package: cowsay-off
Source: cowsay
Version: 3.03+dfsg2-8
Installed-Size: 23
Maintainer: James McDonald <james@jamesmcdonald.com>
Architecture: all

List package names without descriptions

apt-cache pkgnames cowsay

pkgnames takes a prefix rather than a regular expression, and matches only the start of the name. Debian's shell completion for package names is built on it.

Show output
cowsay
cowsay-off

List every package with a given prefix

apt-cache pkgnames cowsay-

A trailing hyphen is a quick way to see what a source package split itself into, once you know the naming pattern a project uses.

Show output
cowsay-off

Check a package name exists before using it

apt-cache pkgnames cowsay | grep -qx cowsay && echo available || echo "no such package"

grep -qx insists on a whole-line match, so a prefix that also matches longer names cannot pass. Faster than apt-cache show for the same question, because pkgnames never reads the records.

Show output
available

Count what a search would return

apt-cache search --names-only cow | wc -l

Worth doing before piping a broad search anywhere. The count comes from your machine's cache, so it depends on which repositories are configured.

Show output

Your output will differ: the count depends on which repositories your machine has configured and when it last updated

22

Count every package name apt knows

apt-cache pkgnames | wc -l

The size of the archive as your machine sees it. Adding a repository, or enabling contrib and non-free, moves this number.

Show output

Your output will differ: the count moves with the archive and with which components are enabled

68194

Following dependencies

depends reads forwards, from a package to what it needs; rdepends reads backwards, from a package to what needs it. Both answer from the archive, so neither is limited to what is installed unless you ask for that.

See what a package depends on

apt-cache depends cowsay

Each relationship gets a line, with the kind named on the left. Suggests and Recommends appear here alongside Depends, so this is a longer list than what installing the package would actually pull in.

Show output
cowsay
  Depends: libtext-charwidth-perl
  Depends: <perl:any>
    perl
  Suggests: filters
  Suggests: cowsay-off

Show only the dependencies that are required

apt-cache depends -i cowsay

-i (--important) drops everything that is not a hard requirement, which cuts a long dependency list down to the part that decides whether the package can be installed at all.

Show output
cowsay
  Depends: libtext-charwidth-perl
  Depends: <perl:any>
    perl

Read a virtual dependency

apt-cache depends default-mta

Angle brackets mean a virtual package, a name real packages provide rather than one of their own. Asking about one directly gives the name straight back; where a real package depends on a virtual one, depends indents the providers beneath it, as the <perl:any> line above does with perl.

Show output
<default-mta>

Limit the answer to packages you have

apt-cache depends --installed cowsay

The same query filtered to packages present on the machine, which is a quick way to see what a dependency chain has already brought in.

Show output
cowsay
  Depends: libtext-charwidth-perl

Notice that depends hides version constraints

apt-cache depends cowsay-off

Depends: cowsay here, where the record says cowsay (>= 3.03+dfsg2-3). apt-cache show keeps the ranges, and you need them to work out why apt is refusing to install a particular version.

Show output
cowsay-off
  Depends: cowsay
  Breaks: cowsay
  Replaces: cowsay

Follow a dependency chain all the way down

apt-cache depends --recurse -i cowsay | head -12

--recurse repeats the query on everything it finds. Without -i it follows Suggests and Recommends too, which on a normal package reaches a large part of the archive.

Show output
cowsay
  Depends: libtext-charwidth-perl
  Depends: <perl:any>
    perl
libtext-charwidth-perl
  Depends: libc6
  Depends: perl-base
  Depends: <perlapi-5.40.0>
    perl-base
perl
  Depends: perl-base
  Depends: perl-modules-5.40

List every package a dependency chain reaches

apt-cache depends --recurse -i cowsay | grep '^[a-z]' | sort

Package names are unindented in this output and relationships are indented, so grep '^[a-z]' reduces the chain to the set of packages it touches. This is the whole transitive closure, including what is already installed.

Show output
cowsay
gcc-14-base
libbz2-1.0
libc6
libcrypt1
libdb5.3t64
libgcc-s1
libgdbm-compat4t64
libgdbm6t64
libperl5.40
libtext-charwidth-perl
perl
perl-base
perl-modules-5.40
zlib1g

See how much bigger a recursion gets without -i

echo "important: $(apt-cache depends --recurse -i cowsay | grep -c '^[a-z]')"; echo "everything: $(apt-cache depends --recurse cowsay | grep -c '^[a-z]')"

Following Suggests and Recommends as well turns a chain of a dozen packages into a large fraction of the archive, because those relationships have no reason to converge. Always pass -i unless you specifically want the wider answer.

Show output

Your output will differ: both counts depend on which repositories your machine has configured, and the second is a large fraction of the archive

important: 15
everything: 16690

Spell out the relationships to follow

apt-cache depends --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances cowsay

What -i is shorthand for. The long form is worth knowing because each flag can be used on its own, so you can drop Suggests while keeping Recommends.

Show output
cowsay
  Depends: libtext-charwidth-perl
  Depends: <perl:any>
    perl

Find out what depends on a package

apt-cache rdepends cowsay

What would be affected if this package went away. Packages appear once per relationship rather than once each, which is why cowsay-off is listed three times: it declares Depends, Breaks and Replaces on cowsay.

Show output
cowsay
Reverse Depends:
  cowsay-off
  presentty
  junior-games-text
  games-toys
  cowsay-off
  cowsay-off
  ansible
  ansible-core

Get a reverse dependency list without duplicates

apt-cache rdepends cowsay | tail -n +3 | sort -u

tail -n +3 drops the two header lines and sort -u collapses the repeats, leaving one line per package. Worth doing before counting anything.

Show output
  ansible
  ansible-core
  cowsay-off
  games-toys
  junior-games-text
  presentty

Show only packages that truly require it

apt-cache rdepends -i cowsay

The same filter as on depends, and it changes the answer considerably. Most of the list above is Suggests and Recommends, so only these two would actually break.

Show output
cowsay
Reverse Depends:
  cowsay-off
  presentty

Check whether anything installed needs a package

apt-cache rdepends --installed cowsay

An empty list under the header means nothing on this machine depends on the package, so removing it will not take anything else with it. Compare with apt remove --dry-run, which answers the same question from the other direction.

Show output
cowsay
Reverse Depends:

The cache itself

The cache is a binary index built from the files apt update downloads into /var/lib/apt/lists/. These commands describe it rather than any package in it, and the numbers they print will differ on every machine.

See how big the package cache is

apt-cache stats | head -3

Total package names counts every name apt has seen, real and virtual. It is far larger than the number of installable packages, which the next lines break down.

Show output

Your output will differ: every figure here depends on which repositories your machine has configured and when it last updated

Total package names: 159757 (5112 k)
Total package structures: 143561 (6317 k)
  Normal packages: 67868

Tell real packages from virtual ones

apt-cache stats | grep -E 'Normal|virtual'

Normal are packages you can install. The other three count virtual names: Pure where no real package carries the name at all, as with default-mta, Single where exactly one package provides it, and Mixed where a real package of that name exists as well.

Show output

Your output will differ: the counts depend on which repositories your machine has configured

  Normal packages: 67868
  Pure virtual packages: 1097
  Single virtual packages: 64623
  Mixed virtual packages: 327

Rebuild the cache from the downloaded lists

apt-cache gencaches

Re-reads /var/lib/apt/lists/ and rewrites the binary index without fetching anything. The repair for a cache that has been corrupted, and the one apt-cache command that writes to disk.

Show output
Reading package lists...