All pages
Errors
Every failure answers in the same shape, and the useful field is the one naming what to do next. Branch on the code, never on the wording: the sentence is written for a person and it will be reworded.
{
"error": "a sentence for a person",
"code": "health_gate_failed",
"next": "the one thing to do about it",
"details": { }
}
code is a closed list. next names the command or the
call to make now. details is typed per code and absent otherwise. The CLI
prints the error and then next on its own line, and --json prints
the server's body unchanged.
Every code
| Code | Status | What it means |
|---|---|---|
bad_request
| 400 | The request is malformed or missing a field. The answer names which. |
unauthorized
| 401 | No key, or a key that does not resolve. Sign in, or set the key variable. |
scope_required
| 403 | The key resolves but lacks the scope. Mint one that has it. |
self_only
| 403 | A machine’s own token reached past the machine it was minted for. Act on that machine, or use an API key for anything wider. |
repo_not_connected
| 403 | This organization has no claim on the repository named. Connect it with an admin-scoped key, or send a tar of the directory instead. |
not_found
| 404 | No such object, or this key belongs to another organization. |
conflict
| 409 | An operation is already running on it. Wait for it to finish. |
volume_in_use
| 409 | A volume is attached or mounted elsewhere. The answer names what holds it. |
payload_too_large
| 400 | A field is too big to live in a replicated row. Put the value in a volume or in object storage and reference it. |
quota_exceeded
| 429 | The organization is at a ceiling. The answer names which limit. |
no_capacity
| 507 | The request was fine and the fleet has no room for the machine. Ask for a smaller one, free some, or add a host. |
not_configured
| 400, 501, 503 | This host or fleet was built without the piece. The answer names it. |
not_implemented
| 501 | The route is not built yet. |
unavailable
| 503 | The host that writes this object is unreachable. Retry in a minute. |
internal
| 500 | The host broke. Retry once, and say so if it repeats. |
plan_unsupported
| 400 | The compose file asks for something pilots does not do. |
compose_invalid
| 400 | The compose file does not parse. The message names the file. |
unknown_framework
| 400 | No compose file, no Dockerfile, no recipe. |
plan_multi_service
| 400 | A push tried to deploy a repository holding more than one app. |
build_failed
| on the log line | The build stopped. The line carrying the failure says where. |
health_gate_failed
| 422 | The replica never answered its health check. |
The two that carry details worth reading
health_gate_failed carries the service, the replica, the
release, the grace it was given, and the last thing the probe saw: a status and a body
when the replica answered, and an error when it did not. It carries NO address, because
the probe target is the host's own view of the replica and is not reachable from where
you are reading the error. A refused connection there means one of two things and almost
nothing else: the app is listening on the wrong port, or it bound the loopback address
instead of all interfaces.
unknown_framework carries the directory, what was looked for,
the listing, the manifests, any workspaces, and the rules a Dockerfile must obey. That is
enough to write one without opening the repository again
(deploy).
What to do
| You got | Do |
|---|---|
| Any error |
Read next and do that.
|
health_gate_failed
| Diagnose the replica named in the answer, then fix the app. Do not redeploy first. |
build_failed
| Read the log line carrying the failure, fix it, build again. |
unknown_framework
| Write the Dockerfile from the details, build with it, and deploy that build under a name. |
internal
| Retry once. If it repeats, say so rather than working around it. |
A 503 about a machine whose owner is gone
| Retry. The host that would bring it back is still joining the fleet and claims nothing until its replica has caught up. A host says so about itself on its health route, and it clears itself within seconds. |
Three habits to avoid
- Parsing the sentence. It is for a person and it will be reworded.
- Retrying a failed health gate by deploying again. Nothing changed, so nothing will.
- Treating a
not_foundas proof the object does not exist. A key scoped to another organization gets the same answer, on purpose.