-
Notifications
You must be signed in to change notification settings - Fork 0
Retries and Timeouts
Two manifest keys control retry behaviour — retries and retrywait — and both apply to
downloads only. Everything else is either a fixed timeout in the code or no timeout at all.
This page states which is which, because the difference decides whether a bad item costs
you thirty seconds or an unbounded wait.
retries is the total number of download attempts for an item's payload, not the
number of extra tries after the first. The default is 3. After each attempt the file's
SHA-256 is recomputed and compared against hash; a match ends the loop, anything else
counts as a failed attempt.
retrywait is the number of seconds slept between attempts. The default is 5. The sleep
also runs after the final failed attempt, so an item that never succeeds costs
retries × retrywait seconds of sleeping in addition to the transfer time — with the
defaults, about 15 seconds of waiting before the item is given up on.
Both keys accept an integer or a string containing one, so 3 and "3" both decode.
A failing download logs one line per attempt and then a final line:
Hash mismatch or download failed for /Library/Application Support/BootstrapMate/munkitools.pkg. Retrying in 5s...
All retries failed for /Library/Application Support/BootstrapMate/munkitools.pkg.
Because HTTP status codes are not inspected, a 404 or an authentication failure reaches you as a hash mismatch on this path rather than as an HTTP error.
Nothing else is retried. A package whose installer run exits non-zero fails
immediately. A script that exits non-zero fails immediately. A manifest that fails to
download or decode ends the run with exit 1 without a second attempt. If you need an
operation retried, put the retry inside the script.
None of these are settable from the manifest — there is no per-item timeout key.
| Wait | Limit | On expiry |
|---|---|---|
| Manifest download | 60 s | Run exits 1 |
| One item download attempt | 120 s | Counts as a failed attempt; the retry loop continues |
| Network availability at startup |
--network-timeout, default 120 s |
Logged, run continues anyway |
| Data volume writable | 30 s | Logged, run continues anyway |
| Waiting for management configuration | 300 s | Logged; without a manifest URL the run then exits 1 |
Run-summary POST to reportingUrl
|
15 s request, 20 s overall | Logged only; never fails the run |
The startup network wait is the only one with a knob, and only from the command line: a
networkTimeout set by configuration profile is read but not used. See
Preferences.
-
A package install.
/usr/sbin/installeris waited on with no ceiling. A package that hangs hangs the run. -
A synchronous script. A
rootscriptoruserscriptwithoutdonotwaitis waited on with no ceiling. An interactive prompt, aread, or a network call with no timeout of its own will stall provisioning indefinitely, and because there is no console it will never be answered. -
Waiting for a user session. The
userlandstage polls every two seconds for a console user and will wait forever. A Mac that enrols and is never logged into stays in this state with the dialog showing "Waiting for user to log in...".
There is no watchdog and no overall run deadline. A hung item is a hung run: every later item and stage waits behind it, the LaunchDaemon is never torn down, and no run summary is reported. Recovering means killing the process on the machine.
Script authors should build their own limits — wrap slow calls, and never wait on input.
donotwait: true on a script is the one way to keep a long-running item from blocking the
rest of the run. The script is launched, the item is recorded as a success as soon as the
process starts, and BootstrapMate moves straight on. Its exit code is never read and its
output is not captured, so it can neither fail the run nor tell you anything. It has no
effect on package items.
Fire-and-forget children survive BootstrapMate's teardown, which is what makes donotwait
the right tool for starting the ongoing management run — see
Handoff to Munki — and the wrong tool for anything whose result you
need to know.
-
A
preflightscript that fails to download or launch stops everything:setupassistantanduserlandare both skipped and the run exits 1. -
A
setupassistantoruserlanditem that fails is recorded, and the stage carries on with the next item. Both stages run to the end. The run's final exit code is 1, and the dialog closes on "Setup completed with errors". -
Any failure means the success-only steps are skipped: a requested
--rebootdoes not happen unless the run succeeded.
Either way, cleanup still runs — the one-shot LaunchDaemon removes itself even after a failed run, so a failure does not leave the bootstrap armed to retry at next boot.