Dear maintainers,
#1111554 (merged with #1117797 and #1124940) was treated as log spam and
fixed in 3.1.8 by moving the message to debug output. On trixie, which
still ships apt 3.0.3, the same loop also exhausts memory, and that took
down a Proxmox VE 9 host (Proxmox VE 9 uses Debian's apt 3.0.3).
What happens:
- In pkgAcquire::Run (apt-pkg/acquire.cc), when the head item of a queue
is idle with a FetchAfter time in the past and Queue::Cycle() cannot
start it (the queue's pipeline is full with a slow download),
fetchAfter is set to now, select() gets a zero timeout and the loop
runs again at once.
- Every pass calls _error->Warning("Tried to start delayed item %s, but
failed"). Warnings are kept in the global error list until apt prints
them at the end, so memory grows by one message per pass for as long
as the slow download lasts.
What we measured (apt 3.0.3, Proxmox VE 9.1 / Debian 13, default
apt settings, "apt-get --download-only dist-upgrade", run in a memory-
capped systemd scope):
- 1,351,886 such warnings held about 355 MB in apt before it finished.
- In the real incident on 30.10.2026 apt grew to 14.5 GB, the kernel
OOM-killed an 8 GB virtual machine and the host froze.
- Trigger: one transient failure (a 5xx, a refused or timed-out
connection, or a connection closed mid-body) on one file while another
file from the same mirror is still downloading slowly, so the retried
item sits idle behind it.
- With Acquire::Retries=0, or when every file comes from a local cache,
the warnings do not appear and apt stays at about 75 MB.
Requests:
1. Please consider the 3.1.8 change for trixie (a stable update): every
trixie and Proxmox VE 9 system still has the memory growth.
2. Even with the message moved to debug, the loop itself still spins with
a zero timeout (fetchAfter = now) until a pipeline slot frees up, so
it still burns CPU. Waiting for the queue instead of re-polling at once
would fix both.
We can provide the reproduction script and logs if useful.
Thank you for apt.