Skip to main content

API errors

Errors are returned as application/problem+json per RFC 7807. The shape is the same across endpoints, so one error handler is enough. What does need separating is a request that was rejected outright from an operation that was accepted and failed later.

The error body

The standard RFC 7807 members are present on every error response: type, title, status, detail and instance. title and detail are written for humans and may be reworded without notice — never parse them or compare them as strings.

On top of the standard members the API adds code: a stable machine-readable identifier of the specific error condition. That is what your code should branch on. When there is no such identifier, the field is omitted.

code is declared on only one response today

In the current schema the type carrying code is declared on exactly one response — the 409 from VM creation, where code is insufficientCapacity. Every other error response is typed with the base problem details shape that has no code. Write your handler so a missing field is harmless: read code when present and fall back to the HTTP status when it is not.

Status codes

  • 400 — the request failed validation. The body carries an errors map of field name to messages. Bad sorts and filters land here too, for example a field the endpoint does not support.

  • 401 — the request is not authenticated: no valid Keycloak session or bearer token.

  • 404 — the resource was not found. Check that the identifiers in the path belong to the same project; a VM from another project looks missing.

  • 409 — a state conflict. Most often another operation is already running on the resource.

  • 503 — the endpoint is temporarily disabled. VM resize currently answers this for any input.

409 conflicts and what to do about them

409 covers several distinct situations, and each calls for a different reaction.

  • Busy with another operation. While an operation runs on a VM, network or address, other changes to the same resource are rejected. Wait until the resource's status leaves creating, updating or deleting, then retry.

  • Out of capacity. VM creation returns code set to insufficientCapacity. Nothing is charged and no VM is created. Retry later or pick a smaller configuration — the configurations list shows this in advance through availability and maxCount.

  • Still in use. A project cannot be deleted while it owns VMs, networks or public IPs; an SSH key cannot be deleted while it is authorized on a VM; a public IP cannot be released while it is attached. Remove the dependency first.

A rejected request is not a failed operation

A 202 means the work was accepted. If it fails later there is no HTTP error to catch — the operation record carries the outcome. Its status becomes Failed and failureCode says why.

  • insufficientCapacity — no node could fit the requested configuration.

  • timeout — the operation did not finish within its allotted time.

  • internal — any other or unclassified cause.

Remember that a failure handled normally leaves the resource active. That means the resource's status cannot tell you the outcome — read the operation. See Statuses and lifecycle for the details.

What to log

Log status, code and instance from the error body, and for async failures the operation id together with failureCode. An operation's currentState reads well for a human but its set of values is not stable, so do not build conditions on it.