Skip to content

Document accepted kill_timeout formats in fly.toml reference - #2465

Draft
alexleventer wants to merge 1 commit into
mainfrom
kill-timeout-formats
Draft

Document accepted kill_timeout formats in fly.toml reference#2465
alexleventer wants to merge 1 commit into
mainfrom
kill-timeout-formats

Conversation

@alexleventer

Copy link
Copy Markdown

Background

This started from a report that kill_timeout is integer-only and that agents keep writing kill_timeout = "30s" as "broken schema."

That premise doesn't hold. Verified against flyctl v0.4.86 (fly config show --local):

Value Parses as
kill_timeout = 30 "30s"
kill_timeout = "30s" "30s"
kill_timeout = "5m" "5m0s"
kill_timeout = "30" time: invalid duration — missing unit
kill_timeout = 0.5 "0s" — silently truncated

Both forms normalize identically. Our own blueprints/long-running-tasks already uses "30s".

What was actually wrong

  1. The reference said "(in seconds)" and only ever showed kill_timeout = 120, never mentioning the duration-string form — which is how someone reading only this section concludes "30s" is invalid.
  2. The two genuinely broken forms were documented nowhere: "120" (parse error) and 1.5 (silently becomes 0 seconds — no grace period at all).
  3. The real footgun: kill_timeout inside machine_checks parses differently from the top-level key. An unquoted 5 there is read as 5 nanoseconds. Two keys, same name, opposite rules.

Changes

  • Callout (warning icon, the most prominent class in this repo) directly under the section intro, with a wrong-vs-right TOML block — visible on a skim, not just a targeted search.
  • Note on the Go duration units and a pointer to fly config validate.
  • Cross-referenced note on the machine_checks.kill_timeout nanosecond behavior, in both directions.

Not addressed here

Two adjacent factual bugs I left alone since they're out of scope for this change:

  • reference/configuration.html.markerb:98 — the shutdown sequence says it ends with "SIGTERM unconditionally"; that should be SIGKILL.
  • The reference says kill_signal defaults to SIGINT, while blueprints/long-running-tasks.html.md:180 says SIGTERM. One of them is wrong.

🤖 Generated with Claude Code

The reference only ever showed `kill_timeout = 120` and described it as
"(in seconds)", which reads as though the bare-integer form is the only
valid one. It isn't: flyctl accepts both an unquoted number of seconds
and a quoted Go duration string, and normalizes them identically.
Readers (and agents) working from this section were flagging valid
configs like `kill_timeout = "30s"` as broken schema.

Add a callout with wrong-vs-right examples covering:

- both valid forms
- `"120"` — a quoted number with no unit is a parse error
- `1.5` — a decimal is silently truncated to 0, leaving no grace period

Also document the sharper footgun: the `kill_timeout` key inside a
`machine_checks` section parses differently from the top-level one. An
unquoted `5` there is read as 5 nanoseconds, so that key always needs
the quoted, unit-bearing form.

Verified against flyctl v0.4.86 via `fly config show --local`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant