API error codes
Updated
Errors use a stable code for programs and a human-readable message:
{ "code": "INVALID_STATE", "message": "VM 'demo-api-vm' in state Running does not allow this operation"}Callers should branch on code, not message.
Response shapes
Section titled “Response shapes”Most Virtainer application errors use the JSON envelope above. A few responses are intentionally different:
| Status | Content type | Body | Description |
|---|---|---|---|
204 No Content | none | empty | Successful lifecycle and delete operations do not return JSON. |
4xx or 5xx | JSON | { "code": "...", "message": "..." } | Standard Virtainer application error. |
422 Unprocessable Entity | text | plain text | Axum rejected the JSON body before the handler ran, usually because a required field was missing or a value had the wrong type. |
Common codes
Section titled “Common codes”| Code | Meaning |
|---|---|
BAD_REQUEST | The request body or parameter is invalid. |
UNAUTHORIZED | The bearer token is missing or invalid. |
FORBIDDEN | The key is valid, but the endpoint is outside the API key allowlist, or a read-only key attempted a mutation. |
NOT_FOUND | The resource does not exist. |
ALREADY_EXISTS | A VM or template with that id already exists. |
CONFLICT | A related operation is already in progress, such as an AppVM image import. |
INVALID_STATE | The requested action does not match the current VM state. |
CH_ERROR | Cloud Hypervisor returned an error. |
NETWORK_ERROR | Host network setup or realization failed. |
STORAGE_ERROR | Image, disk, qsd, or storage work failed. |
INTERNAL | The host returned an unexpected server error. |
Common statuses
Section titled “Common statuses”| Status | Meaning |
|---|---|
400 Bad Request | The handler understood the JSON but rejected a field, combination, or host-side precondition. |
401 Unauthorized | Missing or invalid bearer token. |
403 Forbidden | Valid key, but insufficient scope or endpoint is outside the API key allowlist. |
404 Not Found | Resource id does not exist. |
409 Conflict | Duplicate id, invalid lifecycle state, capacity/admission conflict, or in-progress operation. |
422 Unprocessable Entity | JSON deserialization failed before handler validation. Body is plain text. |
500 Internal Server Error | Host-side storage, network, Cloud Hypervisor, registry, or unexpected internal failure. |
Retry rules
Section titled “Retry rules”- Use a stable
vm_idfor create calls so retries do not create duplicate machines. - Treat
204 No Contentfrom lifecycle actions as accepted by the host, not as proof that the guest is ready. ReadGET /api/vms/{id}afterward. - On
ALREADY_EXISTS, readGET /api/vms/{id}and compare it with your intended machine. - On
INVALID_STATE, read the current state before trying another action. - On
5xxorCH_ERROR, mark the operation as unknown and read state before retrying. Do not assume failed mutations were fully rolled back.