When an install fails¶
Every failure the engine reports names what it was doing and stops there — resolution finishes before installation, so a failure is a report, not a half-installed machine. What you do next depends on which of these it is.
The dry run seems to hang¶
hammunition install navigation --dry-run can take minutes before it prints a
line. It has not hung: the plan checks every terrain tile, map sheet, book and
map it would download against the publisher, one request each, because each
answer (size, checksum) is part of what the plan tells you. On a terminal it
says so on stderr (checking 412 terrain tiles … (needs the network)…) with a
count. If you see nothing at all, stderr is not a terminal; run it with
HAMMUNITION_PROGRESS=1 in front, or in a terminal rather than through a pipe
or a log. A repeat dry run is fast now: an item already installed that the transaction
log attributes to the engine is not asked about again for seven days (the plan
says N installed data item(s) were not re-checked, and --json lists each in
publisher_checks), and only a first install or an older attribution costs the
requests. hammunition install … --recheck asks every publisher regardless, for
when you suspect one re-issued a file. With the network down
a request that cannot connect is retried, then the host is given up on after
three such failures in a row and each remaining request is asked once (a
publisher answering 503 for everything is treated the same); a blackholed
connection still waits out its own 30 s timeout, four at a time, so a few
hundred tiles can take a long while to refuse. Interrupt with Ctrl-C, fix the
connection and run again.
The plan said a publisher is not answering¶
Will NOT happen (the rest of the transaction still will):
usgs-ustopo: will not fetch 3 item(s) this run: <sheet>, <sheet>, <region> (its outline)
why: the publisher is not answering right now (prd-tnm.s3.amazonaws.com answered
HTTP 503); 3 attempts each, then given up
Nothing is wrong with your station or the catalog. A publisher (a Geofabrik outline, the USGS bucket, Kiwix, a CDN) answered a 5xx, dropped the connection or timed out three times running for those items, and the plan left them out rather than refuse everything else. Run the same command again in a few minutes: the items are asked again and, once the publisher is back, planned as usual. Anything of theirs already on disk was kept; when the deferred item is a Kiwix book or a CoMaps map, the unit removes no unlisted file in that run, so a book you deselected goes at the next complete one. A certificate that does not verify is never treated as an outage: it refuses by name.
hammunition install <unit>(the unit named in the line) asks again for just that unit and, if the publisher still does not answer, refuses with its last answer instead of deferring.hammunition statuskeeps listing the deferral for as long as that was your latest transaction.- An HTTP 404 on a sheet is a different message and a different fix: the
carried index is stale, and the line names
scripts/gen_ustopo_index.py --fetch. That is not an outage and is never deferred. - Retry lines on stderr (
retrying (attempt 2 of 3)) show only on a terminal, or withHAMMUNITION_PROGRESS=1in front.
A source build fails to fetch — HTTP 404¶
A pinned upstream URL moved or the project stopped publishing that artifact. This is a catalog bug, not your machine — the manifest's URL needs updating. Open an issue with the package name, or if you maintain a checkout, run the sweep that catches these:
It knocks on every pinned URL in the catalog and reports the dead ones, keeping them apart from hosts that merely flaked today.
A git build stops in a text editor¶
$ git -C …/build/comaps-…/src tag -f v2026.08.31-14 FETCH_HEAD
GNU nano … .git/TAG_EDITMSG
## Write a message for tag:
Your own git configuration turned a plain tag into a signed one. With
tag.gpgsign true (or tag.forceSignAnnotated true) in ~/.gitconfig,
git tag NAME creates an annotated tag, which needs a message, so git opens
your editor and the install waits in it. Nothing is wrong with the build.
Engines from v0.20.0 on run every git step with the operator's signing
settings turned off for that one command and with no editor and no terminal
prompt, so this cannot recur. On an older engine, type any word, save and
leave the editor (Ctrl+O, Enter, Ctrl+X in nano); if signing then fails
for want of a key, the step fails and a rerun of the same command resumes
from the cache once the engine is updated. Your git configuration is never
changed.
apt refuses with "held broken packages" on Parrot¶
E: Unable to correct problems, you have held broken packages.
… libcurl4t64 … is selected as a downgrade …
Seen on Parrot Security with backports enabled: its backports stream ships
updated runtime libraries (libcurl, GTK, SDL2, some Qt6), but the base
-dev packages a source build needs conflict with them. The remedy is to take
the development packages from backports too:
The engine's failure text lists exactly which packages apt could not reconcile — those are the ones to pull from backports. This is a distribution-state issue, not a catalog one; Debian and Kali do not show it.
python3 -m venv fails with ensurepip¶
A Debian netinst ships no python3-venv, which the engine's source and
hybrid backends need. One command:
Parrot and Kali ship it. A future .deb install of Hammunition will carry its
own virtualenv and remove this step entirely.
A vendor .deb is refused for a file collision¶
wsjtx-improved: its vendor .deb collides with installed distribution
package(s): wsjtx-data
→ remove them first (sudo apt-get remove wsjtx-data) …
This is the engine protecting you, not failing. wsjtx-improved's vendor
.deb ships a file that the distribution's wsjtx-data (a jtdx dependency)
also owns, with no Replaces header, so installing it would leave dpkg's
database inconsistent. The engine refuses at plan time and names the remedy —
remove the conflicting package first if you want the improved build, or keep
what you have. It never removes a distribution package silently (D-022).
A package is "refused by name" for a backend or repo¶
Also not a failure. The engine will not pretend to support something it cannot actually do — adding a third-party apt repository with a pinned signing key is a disclosed modification it does not yet implement, so it refuses by name and tells you to install that one package by hand. A capability matrix that reported coverage the engine does not have would be the lie this rule exists to prevent. The rest of your transaction is unaffected; install the named package yourself, or choose one that needs no third-party repo.