You type apt install, hit enter, and Debian calmly replies: “Unable to locate package …”. The package exists. Your coworker installed it last week. Your muscle memory insists it should work.
This error isn’t a single problem. It’s a family of misconfigurations and stale assumptions—suite names, components, architectures, mirrors, keys, pinning, and sometimes just your own optimism. Let’s hunt it down like adults.
Fast diagnosis playbook (do this first)
When production is waiting and you don’t have time for a philosophical debate with APT, do this in order. The goal is to identify whether the bottleneck is metadata, repositories, architecture, or policy.
1) Confirm APT’s view of the world (metadata freshness)
- Run
apt-get updateand read the errors, not just the exit code. - If you see
NO_PUBKEY,403,404, orRelease fileproblems, stop. Fix that first.
2) Ask APT whether it knows the package name at all
apt-cache show pkgandapt-cache policy pkgtell you if the package exists in your configured repos.- If APT doesn’t know it, the issue is sources/components/suite/arch/mirror sync.
3) Validate suite and components (the most common Debian 13 trap)
- Check that your suite matches reality (e.g.,
trixievsstablevstesting). - Ensure
non-free-firmwareis present if you expect firmware packages.
4) Validate architecture and multiarch
- Confirm
dpkg --print-architecture. - If you’re trying to install
:i386on amd64, add the architecture and update.
5) Check pinning / preferences
apt-cache policywill show pins and candidate selection.- Pinning rarely produces “Unable to locate package”, but it often produces “no installation candidate” and gets misreported in tickets.
If you do those five, you’ll usually have the culprit in under ten minutes. If not, you’re likely in mirror sync hell or dealing with a repo that stopped publishing for your suite/arch.
What “Unable to locate package” actually means
APT isn’t telling you “the package doesn’t exist in Debian.” It’s telling you something narrower and more annoying:
- APT’s local package index does not contain that package name for any enabled repository, suite, component, and architecture combination.
- Or you’re asking for a package name that doesn’t match any package in those indexes (typo, renamed package, transitional package removed).
That’s why the same package can exist on Debian’s servers, and still be “unlocatable” to your host. Your host is only aware of what it has indexes for. Indexes come from configured repositories. Repositories are sliced by:
- Suite (e.g.,
trixie,stable,testing) - Component (e.g.,
main,contrib,non-free,non-free-firmware) - Architecture (e.g.,
amd64,arm64,i386)
Miss one slice and the package disappears from APT’s universe.
Also: Debian 13 pushes more people into the “new sources format” and stricter keyring habits. This is good engineering. It is also a fresh supply of ways to shoot yourself in the foot—cleanly, deterministically, and at scale.
Facts and context that explain the weirdness
- Fact 1: Debian splits repositories into suites and components to separate stability goals and licensing constraints; your config decides what APT can “see.”
- Fact 2: Debian introduced the
non-free-firmwarecomponent (separate fromnon-free) so firmware can be enabled explicitly without dragging in everything else. - Fact 3: Multiarch in Debian lets you install foreign-architecture packages (like
:i386on amd64), but APT won’t fetch those indexes unless you add the architecture. - Fact 4: APT’s error messages are precise but not always friendly: “Unable to locate package” is about missing index entries, not network reachability or DNS (those usually show up during
apt update). - Fact 5: Debian’s repository metadata is signed; modern setups prefer per-repo keyrings with
signed-by=rather than dumping keys into a global trust bucket. - Fact 6: Mirrors can be temporarily out of sync; during transitions you can legitimately see packages missing on one mirror and present on another.
- Fact 7: Debian supports both
sources.listand deb822-style.sourcesfiles; mixing them casually can produce duplicates, conflicting suites, or surprising pin behavior. - Fact 8: Packages get renamed, split, or removed across releases; the name you remember from older Debian may now be a transitional package or gone entirely.
One quote worth keeping taped to your monitor:
“Hope is not a strategy.” — Gene Kranz (paraphrased idea)
Practical tasks: commands, outputs, decisions (12+)
These are the checks I run on real servers. Each task includes: command, a realistic snippet of output, what the output means, and the decision you make next.
Task 1: Confirm your Debian version and codename (don’t guess)
cr0x@server:~$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
NAME="Debian GNU/Linux"
VERSION_ID="13"
VERSION="13 (trixie)"
VERSION_CODENAME=trixie
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
Meaning: You are on trixie. If your sources list points to bookworm or stable in a pinned environment, expect surprises.
Decision: Align sources to trixie (or consciously choose stable/testing labels with pinning you can explain to your future self).
Task 2: Run update and actually read it
cr0x@server:~$ sudo apt-get update
Hit:1 http://deb.debian.org/debian trixie InRelease
Hit:2 http://security.debian.org/debian-security trixie-security InRelease
Get:3 http://deb.debian.org/debian trixie-updates InRelease [55.4 kB]
Reading package lists... Done
Meaning: Indexes were fetched successfully. If you still can’t locate a package, it’s probably suite/component/arch/name—not connectivity.
Decision: Move to package discovery tasks (policy/show/search) instead of debugging DNS.
Task 3: Catch signature/key problems early
cr0x@server:~$ sudo apt-get update
Get:1 https://repo.vendor.example/debian trixie InRelease [3,214 B]
Err:1 https://repo.vendor.example/debian trixie InRelease
The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 0123456789ABCDEF
Reading package lists... Done
W: GPG error: https://repo.vendor.example/debian trixie InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 0123456789ABCDEF
E: The repository 'https://repo.vendor.example/debian trixie InRelease' is not signed.
Meaning: APT refuses to trust the repo; packages from it are effectively invisible.
Decision: Install the vendor key into a dedicated keyring and reference it with signed-by= in the source entry (don’t use deprecated global key dumping).
Task 4: Print configured sources (both old and new formats)
cr0x@server:~$ grep -R --no-filename -nE '^(deb|Types:)' /etc/apt/sources.list /etc/apt/sources.list.d/* 2>/dev/null
1:deb http://deb.debian.org/debian trixie main
2:deb http://deb.debian.org/debian trixie-updates main
3:deb http://security.debian.org/debian-security trixie-security main
/etc/apt/sources.list.d/vendor.sources:1:Types: deb
Meaning: You have classic sources.list entries and at least one deb822 .sources file.
Decision: Inspect deb822 files too; plenty of “missing package” incidents are simply “wrong suite in the other file you forgot existed.”
Task 5: Inspect a deb822 source file for suite/component mistakes
cr0x@server:~$ sed -n '1,120p' /etc/apt/sources.list.d/vendor.sources
Types: deb
URIs: https://repo.vendor.example/debian
Suites: stable
Components: main
Signed-By: /usr/share/keyrings/vendor-archive-keyring.gpg
Meaning: That repo is pinned to stable. On Debian 13 that might be fine, or it might be incompatible with vendor packages that publish only for specific codenames.
Decision: If vendor documentation expects trixie, switch suite. If they only publish bookworm, stop and reconsider—mixing is a risk you should justify.
Task 6: Verify APT knows the package name
cr0x@server:~$ apt-cache show zfsutils-linux
N: Can't select versions from package 'zfsutils-linux' as it is purely virtual
Meaning: The name exists but is virtual; you may need a provider package, or the package naming changed in your suite.
Decision: Use apt-cache showpkg or apt-cache policy to identify providers; don’t keep retrying apt install like it’s a slot machine.
Task 7: Check candidate versions and repo origins
cr0x@server:~$ apt-cache policy openssl
openssl:
Installed: 3.3.1-1
Candidate: 3.3.1-1
Version table:
*** 3.3.1-1 500
500 http://deb.debian.org/debian trixie/main amd64 Packages
100 /var/lib/dpkg/status
Meaning: APT sees the package, sees its origin, and has a candidate. This is what “healthy” looks like.
Decision: If your missing package doesn’t show a Version table at all, it’s not in enabled indexes. Go fix sources/components/arch.
Task 8: Use apt-cache search to catch renamed packages
cr0x@server:~$ apt-cache search --names-only '^python3-venv$'
python3-venv - venv module for python3 (default python3 version)
Meaning: Exact package exists. If install still fails, you’re dealing with a different issue (maybe pinning or held packages).
Decision: Install it; if it fails with “no installation candidate,” jump to pinning/tasks around preferences.
Task 9: Confirm the system architecture (and stop installing the wrong thing)
cr0x@server:~$ dpkg --print-architecture
amd64
Meaning: Native arch is amd64.
Decision: If you are trying to install :i386 packages (common for legacy tools), add i386 and refresh.
Task 10: Check enabled foreign architectures (multiarch)
cr0x@server:~$ dpkg --print-foreign-architectures
Meaning: None enabled.
Decision: If the package you want exists only as i386, enable it.
Task 11: Enable i386 multiarch correctly
cr0x@server:~$ sudo dpkg --add-architecture i386
cr0x@server:~$ sudo apt-get update
Hit:1 http://deb.debian.org/debian trixie InRelease
Get:2 http://deb.debian.org/debian trixie/main i386 Packages [9,112 kB]
Fetched 9,112 kB in 2s (4,230 kB/s)
Reading package lists... Done
Meaning: APT now fetches i386 indexes.
Decision: Retry apt install pkg:i386. If still missing, it’s not published for i386 in that suite.
Task 12: Confirm components include what you need (non-free-firmware is a frequent miss)
cr0x@server:~$ grep -n '^deb ' /etc/apt/sources.list
1:deb http://deb.debian.org/debian trixie main
2:deb http://security.debian.org/debian-security trixie-security main
Meaning: Only main is enabled. Firmware packages that live in non-free-firmware will be invisible.
Decision: Add non-free-firmware (and non-free/contrib only if you have an explicit reason).
Task 13: Update sources to include non-free-firmware
cr0x@server:~$ sudo sed -i 's/ main$/ main non-free-firmware/' /etc/apt/sources.list
cr0x@server:~$ sudo apt-get update
Hit:1 http://deb.debian.org/debian trixie InRelease
Get:2 http://deb.debian.org/debian trixie/non-free-firmware amd64 Packages [32.1 kB]
Fetched 32.1 kB in 1s (35.7 kB/s)
Reading package lists... Done
Meaning: You are now indexing that component.
Decision: Retry firmware install; if it works, document why non-free-firmware was enabled (so the next audit doesn’t treat it as accidental).
Task 14: Detect duplicate/contradictory entries (classic + deb822 collision)
cr0x@server:~$ apt-get -o Debug::pkgAcquire::Auth=true update
Hit:1 http://deb.debian.org/debian trixie InRelease
Hit:2 http://deb.debian.org/debian stable InRelease
W: Target Packages (main/binary-amd64/Packages) is configured multiple times in /etc/apt/sources.list:1 and /etc/apt/sources.list.d/debian.sources:1
Reading package lists... Done
Meaning: You’re indexing two suites (trixie and stable) and duplicating targets. That is not “redundancy.” That is “future incident.”
Decision: Pick one approach. Prefer a single deb822 file for Debian official repos on newer systems, or keep a clean classic file—just don’t run both half-heartedly.
Task 15: Validate a package exists in your enabled components
cr0x@server:~$ apt-cache policy firmware-iwlwifi
firmware-iwlwifi:
Installed: (none)
Candidate: 20240811-1
Version table:
20240811-1 500
500 http://deb.debian.org/debian trixie/non-free-firmware amd64 Packages
Meaning: The firmware package is present and comes from the expected component.
Decision: Install it. If it’s missing, you’re either missing the component or using a suite where it’s named differently.
Task 16: Prove a network/proxy issue is corrupting APT’s view
cr0x@server:~$ sudo apt-get update
Ign:1 http://deb.debian.org/debian trixie InRelease
Err:1 http://deb.debian.org/debian trixie InRelease
Could not connect to deb.debian.org:80 (199.232.138.132), connection timed out
Reading package lists... Done
W: Failed to fetch http://deb.debian.org/debian/dists/trixie/InRelease Could not connect to deb.debian.org:80 (199.232.138.132), connection timed out
W: Some index files failed to download. They have been ignored, or old ones used instead.
Meaning: You’re running on stale indexes. “Unable to locate package” may simply be because your package lists are old or incomplete.
Decision: Fix connectivity/proxy/firewall. Until update is clean, treat package availability results as untrustworthy.
Joke 1: APT doesn’t “lose” packages. It just gaslights you until you remember you changed the mirror last month.
sources.list and deb822 traps in Debian 13
Debian 13 setups often contain a mix of old /etc/apt/sources.list and newer /etc/apt/sources.list.d/*.sources (deb822) files. Both work. The trap is when they don’t agree.
Suite confusion: stable/testing vs codenames
Using stable or testing is convenient until it isn’t. When Debian moves, those labels move with it. That’s fine for desktops. In production, it’s how you wake up to a different libc than yesterday.
If your problem is “unable to locate package,” suite confusion shows up like this:
- You’re on Debian 13 (
trixie), but your sources point tobookworm. Packages introduced in trixie won’t exist. - You’re on Debian 13, but a third-party repo only publishes for
bookworm, and you mistakenly set it totrixie. APT sees no Packages index for your suite and silently loses access to those packages.
Component omission: “main” is not the whole OS
Debian’s “main” contains a lot. It does not contain everything people assume is “just Linux stuff.” Firmware is the classic example, especially on laptops, Wi-Fi, and some storage HBAs.
On Debian 13, if you need firmware and don’t have non-free-firmware, you’ll see “unable to locate package firmware-…”. That’s not Debian being broken. That’s Debian being explicit.
Signed-by mistakes: the repo exists, but you don’t trust it
Modern APT prefers scoping trust. Good. But it means you can easily end up with:
Signed-Bypointing at a file that doesn’t exist- a keyring installed, but the repo entry doesn’t reference it
- a repo entry referencing the wrong key (common when key rotation happens)
In all these cases, the repo may be reachable, but packages remain effectively unavailable. APT will warn during apt update. If you ignore those warnings, you earn the error.
deb822 gotcha: one file can define multiple entries
deb822 format is cleaner for automation, but it’s also easier to hide complexity. A file can contain multiple stanzas. People skim the first one and miss the second that pins a different suite or disables a component.
Architecture traps: amd64 vs i386 vs arm64
Architecture problems are boring, which is why they survive in enterprise fleets. You can stare at the repo config for an hour and miss the fact you’re on arm64.
The common patterns
- Wrong hardware architecture: You’re on arm64 (cloud instances, some laptops), but assuming amd64. Some third-party repos don’t publish arm64 packages.
- Multiarch not enabled: You want
:i386, but you never added i386. APT doesn’t fetch i386 indexes. Package is “missing.” - Package isn’t built for your arch: Debian’s official repos may not build every package for every architecture (especially fringe or leaf packages). The package exists, just not for you.
How to prove it quickly
Look at apt-cache policy output. If you see an origin line like:
... trixie/main amd64 Packagesthen you’re looking at amd64 metadata.- If you never see your architecture in repo lines, you’re missing metadata (wrong suite, wrong repo, or update failing).
Components: main, contrib, non-free, non-free-firmware
This section is where “unable to locate package” goes from mystery to paperwork.
What each component means operationally
- main: Debian Free Software Guidelines-compliant. Supported in the normal Debian sense. This is where you want to live.
- contrib: Free software that depends on non-free stuff. It’s a signpost that you’re about to make a tradeoff.
- non-free: Non-free software. Sometimes necessary, often regrettable, always worth documenting.
- non-free-firmware: Non-free firmware. Frequently necessary for hardware to function. Kept separate so you can enable it without fully opening the non-free floodgates.
The most practical advice: enable non-free-firmware only if you need it, but don’t pretend you don’t need it. Half-working network interfaces don’t make you morally superior; they make you late.
Mirror and network issues that masquerade as missing packages
Sometimes the package really is missing—from your chosen mirror, right now. Mirrors drift. Proxies cache incorrectly. Security gateways rewrite traffic. And occasionally an internal mirror is quietly serving last Tuesday’s indexes because its rsync job died.
Mirror out-of-sync symptoms
apt-get updatesucceeds, but you can’t find packages that colleagues can find.apt-cache policyshows unexpectedly old versions across the board.- One environment (dev) sees packages, another (prod) doesn’t, despite “same config.”
How to handle it
In production, don’t randomly switch mirrors on one host. Decide whether you’re using:
- an official mirror (good for laptops and small fleets), or
- a controlled internal mirror (good for reproducibility), or
- a caching proxy (good until it isn’t).
Then monitor it. Yes, monitor your package supply chain like it’s a service. It is.
Pinning and mixed suites: the quiet package assassin
Pinning is powerful. It’s also how you create a system that only one person can update, and that person is on vacation.
Pinning usually causes “no installation candidate” or dependency solver failures, but it contributes to “unable to locate package” when it prevents APT from considering a suite where the package exists—or when you think you enabled a suite but pinning effectively neuters it.
Where pinning hides
/etc/apt/preferences/etc/apt/preferences.d/*.pref- automation that drops files there (image build scripts, configuration management)
What to do
Use apt-cache policy to understand candidate selection. Then decide whether you’re running:
- a single-suite system (recommended for most servers), or
- a mixed-suite system (only if you can explain the dependency story and have rollback muscle).
Three corporate mini-stories from the trenches
Mini-story 1: The incident caused by a wrong assumption
A platform team rolled Debian 13 images for a new batch of storage gateways. The build pipeline “standardized” APT sources by using stable everywhere. That label worked fine in CI. It even worked in staging. Everyone nodded and moved on.
Two weeks later, a vendor package was needed for NVMe telemetry export. The engineer on call tried to install it. “Unable to locate package.” They assumed the vendor repo was down and escalated it. Vendor support responded, politely, that the repo was fine and had packages for trixie.
Here’s the twist: the vendor repo was configured with Suites: stable, but the vendor did not publish under that moving label—only codenames. APT was happily requesting dists/stable, getting a 404, and quietly treating the repo as non-existent after warnings scrolled by during updates.
The incident wasn’t the missing package. The incident was the rollout delay and the scramble to rebuild images while storage teams waited. Root cause was “stable means Debian stable everywhere,” a reasonable human assumption that turned out to be operationally wrong for third-party repos.
The fix was boring: use codenames for third-party repos, and enforce “no warnings on apt-get update” in CI. That last part mattered. Warnings are where APT tells you the truth, in its own emotionally distant way.
Mini-story 2: The optimization that backfired
A different org wanted faster provisioning. Someone added an internal caching proxy in front of Debian mirrors. It cut install times dramatically. Tickets went down. Leadership smiled. Then they scaled to more regions and more network segmentation.
Three months later, a vulnerability response required deploying an updated package across a fleet. Half the hosts said “Unable to locate package,” the other half upgraded fine, and none of it correlated cleanly with OS version. The on-call started blaming Debian mirrors, because that’s what people do when they see inconsistent package availability.
The real issue: the proxy was caching repository metadata aggressively and not respecting release file changes correctly during a mirror transition. It served stale package lists to some segments and newer ones to others, depending on cache eviction timing. APT wasn’t broken; it was being lied to.
They “fixed” it by flushing caches during upgrades, which helped once. But it didn’t solve the systemic risk. Eventually the correct solution was to treat the proxy as a production service: upgrade it, configure correct cache semantics for APT metadata, and add monitoring that compares expected Release file timestamps versus what clients receive.
Optimization is great until you optimize away determinism. The bills come due later, usually at 2 a.m.
Mini-story 3: The boring practice that saved the day
A finance company ran Debian across regulated environments. They had a rule: every base image must ship with a single, version-controlled deb822 file for Debian repos, and the image build fails if apt-get update emits warnings or errors.
It was unpopular. Developers wanted to add repos ad hoc. Some teams complained it slowed experimentation. Security liked it. Operations loved it quietly.
One day, a third-party repo rotated its signing key. Many shops learned this when production deployments started failing. In this company, it was caught during image build because apt-get update failed the pipeline immediately. The fix was applied once (update keyring + signed-by reference), rolled into the base image, and deployments resumed with minimal drama.
They didn’t avoid the ecosystem change. They avoided the blast radius. The practice was boring because it worked, and it worked because it was boring.
Joke 2: If you mix stable, testing, and unstable without pinning, congratulations—you’ve invented a new distribution. Please don’t file bugs about it.
Common mistakes: symptom → root cause → fix
1) “Unable to locate package …” after a fresh install
Symptom: Even common packages can’t be found, or firmware packages are missing.
Root cause: Sources only include main, or sources were not set up (minimal install, custom image).
Fix: Ensure Debian repos exist and include needed components (main plus non-free-firmware if you need firmware). Run apt-get update and verify component indexes are fetched.
2) Package exists on another host but not this one
Symptom: Same OS “version,” different result.
Root cause: Different suite labels (stable vs trixie), different mirror, or one host has stale indexes due to update warnings.
Fix: Compare /etc/apt/sources.list* and apt-get update output. Make update warning-free. Use one mirror strategy.
3) Third-party repo packages “disappear” after changing suite
Symptom: After moving to Debian 13, vendor packages can’t be located.
Root cause: Vendor repo doesn’t publish for trixie (or publishes only under codenames, not stable).
Fix: Set repo Suites: to the vendor-supported codename; if unsupported, don’t force it—use the correct distro release or isolate via containers.
4) “Unable to locate package pkg:i386” on amd64
Symptom: APT can’t locate foreign-arch packages.
Root cause: i386 architecture not added; i386 indexes not downloaded.
Fix: dpkg --add-architecture i386 then apt-get update. Verify i386 Packages are fetched.
5) Package name typo or obsolete name
Symptom: Everyone swears the package name is right. It’s not.
Root cause: Package got renamed/split/removed between suites.
Fix: Use apt-cache search --names-only and apt-cache showpkg. Update automation to new names.
6) Repo is present but ignored due to signature issues
Symptom: Repo lines exist; install says package can’t be found.
Root cause: GPG key missing or wrong; signed-by misconfigured; repo treated as untrusted.
Fix: Fix keyring and Signed-By path; rerun apt-get update until clean.
7) Duplicate entries / mixed formats causing confusion
Symptom: Warnings about targets configured multiple times; inconsistent candidates.
Root cause: Both classic and deb822 entries define overlapping repos/suites.
Fix: Consolidate into one config approach. Remove duplicates. Re-run update and confirm no warnings.
8) Internal mirror or caching proxy serving stale metadata
Symptom: Update “works” but package availability is inconsistent across networks.
Root cause: Mirror sync failure or cache semantics for Release/Packages files are wrong.
Fix: Compare timestamps, bypass proxy for a test, fix mirror jobs, tune cache rules, monitor metadata freshness.
Checklists / step-by-step plan
Checklist A: Make APT trustworthy again (baseline hygiene)
- Run
sudo apt-get update. If there are warnings/errors, stop and fix them. - Search your source config for duplicates and conflicts:
grep -Racross/etc/apt/sources.list*
- Standardize on a single suite naming strategy:
- Use codenames for production pin-stable environments, especially for third-party repos.
- Use per-repo keyrings with
signed-by(orSigned-Byin deb822). - Document why any non-default component is enabled (
non-free-firmware,non-free,contrib).
Checklist B: Diagnose a specific missing package
- Confirm OS codename:
cat /etc/os-release. - Update indexes cleanly:
sudo apt-get update. - Check package visibility:
apt-cache policy <pkg>apt-cache show <pkg>apt-cache search --names-only
- Confirm components in your Debian entries (
main, maybenon-free-firmware). - Confirm architecture:
dpkg --print-architecturedpkg --print-foreign-architectures
- If it’s third-party, validate suite naming and signature trust for that repo.
Checklist C: Avoid reintroducing the problem (fleet/enterprise)
- CI gate: fail image builds if
apt-get updateemits warnings. - One canonical sources file, version controlled (deb822 preferred for clarity).
- Mirror strategy:
- Either official mirrors per host, or internal mirror/proxy with monitoring—not “whatever works today.”
- Track multiarch as a deliberate choice; don’t let random apps add i386 silently.
- Periodic audit: dump sources and pins, compare across fleet.
FAQ
1) Why does apt update succeed but apt install can’t locate the package?
Because apt update only tells you that it fetched some indexes successfully. You might be missing the right suite/component/arch, or using stale indexes after partial failures.
2) What’s the fastest way to tell if the package is in my configured repos?
Run apt-cache policy <pkg>. If there’s no Version table, APT doesn’t see it in enabled metadata.
3) Is Debian 13 special here, or is this just APT being APT?
APT is being APT, but Debian 13-era configs more often include deb822 sources, stricter keyring practices, and widespread use of non-free-firmware—all of which introduce new failure modes.
4) Should I use stable or the codename (trixie) in sources?
For production: prefer codenames for determinism, especially for third-party repos. Labels are fine for developer machines where “moving forward” is the point.
5) I enabled non-free-firmware. Do I also need non-free?
No. Enable the minimum you need. Firmware is often enough; non-free is a broader bucket with different tradeoffs.
6) I’m on amd64 but need an i386 package. Why can’t APT find it?
Because APT won’t download i386 package indexes until you enable multiarch with dpkg --add-architecture i386 and re-run apt-get update.
7) Why do I see warnings about duplicates, and can that cause missing packages?
Duplicates can cause confusing candidate selection and hide real suite mismatches. They also make humans misread the situation. Clean them up; treat “configured multiple times” as a bug.
8) What’s the right way to handle third-party repo signing keys now?
Use a dedicated keyring file and reference it per repo with signed-by= (classic) or Signed-By: (deb822). Avoid global trust buckets and deprecated key management patterns.
9) Could a package be missing because my mirror is out of sync?
Yes. It’s less common day-to-day, more common during transitions. If another mirror sees it and your update is clean, suspect mirror sync or a caching proxy serving stale metadata.
10) When is “Unable to locate package” actually a typo?
More often than anyone admits. Verify with apt-cache search --names-only and stop relying on half-remembered names from older releases.
Conclusion: next steps you can actually do today
Fixing “Unable to locate package” on Debian 13 is rarely about the package. It’s about making APT’s inputs correct: suite, component, architecture, signatures, and fresh metadata.
Do these next:
- Make
apt-get updatewarning-free. Not “mostly fine.” Clean. - Consolidate your sources into one coherent set (avoid silent conflicts between classic and deb822).
- Explicitly enable the components you require, especially
non-free-firmwarefor hardware firmware. - Verify architecture and multiarch before blaming the repo.
- If you run an internal mirror/proxy, treat it like production infrastructure: monitor freshness, not vibes.
Once you can explain why APT sees the world the way it does, “Unable to locate package” stops being a surprise and becomes what it always was: a configuration audit with a short temper.