Error recovery
Capacity and unavailable errors, request limits, safe retries and pending briq outcomes.
{
"error": {
"code": "provider_error",
"message": "the provider did not answer (create); retry in a moment",
"details": { "op": "create", "status": 503 },
"requestId": "req-example"
}
}Use the HTTP status and error.code together. The error catalog lists the known API mappings.
Keep error.requestId and the x-request-id header when reporting a failure.
Include the method, path, time and briq ID. Remove credentials, secret values and file contents.
Capacity and unavailable infrastructure
A 503 provider_error can mean temporary capacity exhaustion, an unreachable service or a timeout.
It does not mean your plan or credential quota was exceeded. Capacity can remain unavailable across several attempts.
It also does not prove the operation made no changes: an answer can be lost after work starts.
For reads, retry after a delay with exponential backoff and jitter. Bound your attempts and total waiting time. For writes, check the resource's current state first. Use the create replay rules below where supported. Repeated failures need the request ID for investigation.
A 502 provider_error means the operation failed. Read the message and inspect current state before retrying.
Some billing failures also return 502. A 500 internal means an unexpected server failure; its generic message cannot identify the cause.
Other server HTTP errors can also use internal. Report persistent failures with their request IDs.
Refusals that need action
| Status and code | Next step |
|---|---|
400 validation | Fix the fields named in message or details. Select an available region when region validation fails. |
401 unauthorized | Supply valid credentials or sign in again. |
403 forbidden | Check credential permissions, team membership and the session's origin. |
403 plan_limit | Reduce the requested resources or change the team's plan. |
402 policy_violation | Use a size, registry or sleep setting allowed by the credential's policy. |
402 quota_exceeded | Release running work, raise the allowed limit or wait for the daily spend cap to reset. |
402 payment_required | Add credits or reduce the resources needed to start. |
404 not_found | Check the route, resource ID, team and file path. |
409 invalid_state | Read the message and current briq or exec state before repeating the operation. |
429 quota_exceeded | Wait at least retry-after seconds. Reduce request frequency. |
A busy machine can return 409 invalid_state; wait a few seconds and check its state again.
An exited process, explicit stop, duplicate name or closed command input needs a different action.
Execution-session limits also use 409: close a session or wait for a command to finish.
Machine-state errors can include lastExit, machineState and providerSaid in details.
Size and protocol errors
A 413 validation means the request body, command or output is too large for one call.
Follow the response's limit. Reduce the payload or read smaller output chunks.
File validation can also return 400, including file-content limits; inspect message and details.maxBytes when present.
A missing readable file returns 404; a failed file write can return 502.
Shell and exec stream calls without a WebSocket upgrade return 426 validation.
Malformed upgrade handshakes return 400 validation. Protocol responses can omit details or requestId.
Use the endpoint's protocol and retain any response headers; do not assume every failure matches the JSON envelope.
Retry creates with the same key
Use Idempotency-Key on supported create, fork and stack-up requests.
After a lost connection, repeat the same path and body with the same key.
A stored response has Idempotent-Replayed: true. Its body can contain the original request ID; keep the current header too.
- 409
idempotency_in_progress: wait briefly, then repeat with the same key and body. - 422
idempotency_mismatch: restore the original path and body, or use a new key for an intentional new operation. - A stored 5xx repeats that error. Check existing briqs and stacks before deciding to start another operation with a new key.
- A replay returns the original snapshot. Read the briq status for its current state.
These keys do not cover every write. Repeating an exec can run the command again.
For command input, seq makes a repeated input write safe.
A busy-input refusal asks for the same seq; a gap reports lastSeq so you can send the next number.
Accepted work can still fail
curl https://api.briq.cloud/v1/briqs/bq_example \
-H "Authorization: Bearer $BRIQ_API_KEY"A create returns HTTP 201 with briq states. wait: false returns without waiting for readiness.
Even with waiting enabled, the wait can end while a briq is still creating.
Start returns HTTP 200 and can still show starting after its wait ends.
Acceptance means the operation was recorded; a pending state does not promise a machine was scheduled or became ready.
Poll GET /v1/briqs/{id} with a delay. Inspect briq.state and briq.error, even after a successful HTTP response.
With MCP, use briq_status. Read briq_logs when the process starts but fails or exits.
Do not create a replacement merely because the first call timed out.
| Outcome | What the status means |
|---|---|
creating or starting | Work is pending. Temporary infrastructure failures can leave an error message while retries continue. |
running | The lifecycle operation reached running. Check application health and command results separately. |
Create ends in error with No capacity in <region> right now | No machine was made and nothing is billed. Create again shortly, or in another region when the environment offers one. It is not retried for you. |
Create ends in error | Creation failed; inspect error. Cleanup attempts to stop any machine created; an unavailable service can delay cleanup. |
Start returns to stopped with error | Starting failed. Inspect the reason before requesting another start. |
Stop returns to running with error | Stopping failed; the briq remains running and metered. Check before asking it to stop again. |
destroying with error | Destruction has not completed. Recovery continues; poll for destroyed. |
Temporary unavailable errors receive bounded job retries. Pending creates can also resume during recovery. There is no fixed completion-time guarantee. Stop client polling at your deadline and retain the briq ID for later checks.
An async exec's HTTP 202 is also an acceptance response. Check its exec status until completion. A nonzero exit code or timeout is a command outcome, even when the status request returns HTTP 200. For streamed commands, require a terminal result. A disconnected socket alone does not confirm completion or cancellation. Stream terminal errors are separate from HTTP error envelopes:
| Terminal code | Meaning |
|---|---|
unsupported, exec_stream_refused | Streaming is unsupported or refused for the running guest. |
not_running, invalid | The command runtime became unavailable or refused the stream. |
exec_cleanup_failed, exec_wait_failed | Cleanup or command completion could not be confirmed. Inspect state before retrying. |
internal, stream_failed, stream_lost | The stream failed; command completion is uncertain. |
cancel_unconfirmed | Cancellation and remote cleanup could not be confirmed. |
session_ended | A shell ended without a confirmed exit code. |
See Run a long command for exec states and input recovery.