apt-cacher stale metadata
Status: MITIGATED 2026-07-13 — roles/apt_cacher_ng/tasks/main.yaml now purges the
volatile index metadata on every run (option 1b below), so make up starts each cacher
with fresh, consistent indices. A server-side config rule (option 1a) is still open as a
“stronger / always-fresh” alternative if the purge proves insufficient. · Filed: 2026-07-13 · Severity: medium
What happened
During a make up rebuild, the oci-mirrors stage failed on thoth with the
ansible apt module’s Failed to update apt cache after 5 retries (empty detail).
The real error, from incus exec atomsk:thoth -- apt-get update:
Err:3 http://deb.debian.org/debian trixie-updates InRelease Sub-process /usr/bin/sqv returned an error code (1): Verifying signature: Message has been manipulatedOnly trixie-updates failed; trixie, trixie-security, and smallstep verified fine.
apt-cacher-ng (ho-oh@hyperion / lugia@kyojin) had cached an InRelease for
trixie-updates whose referenced by-hash indices had since moved, so its signature no
longer matched — Debian trixie’s new sqv (sequoia) verifier rejects it as “manipulated”.
Likely trigger: thoth is kept across make down (oci_mirrors ∈ DOWN_KEEP), so it
re-ran apt update against a cacher whose trixie-updates metadata was stale/inconsistent,
while the freshly-rebuilt hosts (garage, etc.) happened to populate/verify clean.
Immediate fix (applied, manual)
Delete the stale release metadata on both cachers (keeps .deb packages), then re-fetch:
incus exec hyperion:ho-oh -- find /var/cache/apt-cacher-ng -path '*trixie-updates*' \( -name InRelease -o -name Release -o -name 'Release.gpg' \) -deleteincus exec kyojin:lugia -- find /var/cache/apt-cacher-ng -path '*trixie-updates*' \( -name InRelease -o -name Release -o -name 'Release.gpg' \) -deleteincus exec atomsk:thoth -- apt-get update # verifies cleanIf by-hash indices are also stale, broaden to .*/(InRelease|Release|Release\.gpg|Packages.*|.*by-hash.*)$
and systemctl restart apt-cacher-ng.
Hardening options (pick one; roles/apt_cacher_ng)
- Server-side revalidation (preferred). Make apt-cacher-ng always revalidate volatile
index files against upstream so a stale
InRelease/by-hash can’t be served. Intemplates/acng.conf.j2: verify/tuneVfilePattern/PfilePatterncoverInRelease|Release|Packages|by-hash, and ensure the expiration maintenance job actually runs (the ReportPageexpireaction / a cron) rather than relying onExTreshold: 30passive drop. Consider a much shorter TTL for the metadata files specifically. - Client-side belt-and-suspenders. In the
initapt-update task, add arescue:that, on asqv/“Message has been manipulated”/signature-verification failure, clears the cacher’s stale metadata (or retries with-o Acquire::http::No-Cache=true) and retries — so a wedged cache degrades gracefully instead of halting the wholemake up. - Ops runbook. At minimum, document the one-liner above in the apt-cacher healthcheck / runbook so the next occurrence is a 30-second fix, not a diagnosis.
References
- Role:
ansible/roles/apt_cacher_ng/(templates/acng.conf.j2,defaults→acng_expire_threshold_days). - Apt-cacher hosts:
ho-oh(hyperion),lugia(kyojin) —fleet.yaml. - Related: Debian trixie switched apt signature verification to
sqv(sequoia), which is stricter aboutInRelease/by-hash consistency than the old gpgv path.