Errors and Status Codes
Reference for CLI exit codes, SDK exceptions, and REST API error responses.
Roboflow's developer tools share a small set of error categories, surfaced differently in each tool. This page is the cross-cutting reference.
CLI exit codes
The CLI uses four well-defined exit codes so scripts and AI agents can branch on outcome without parsing output:
0
Success
1
General error (bad input, network failure, unexpected server response)
2
Authentication failure (missing or invalid API key, no workspace selected)
3
Resource not found (project, version, workflow, deployment, etc. doesn't exist or isn't visible to your key)
In --json mode the CLI writes structured output to stdout on success and a JSON error object to stderr on failure, leaving stdout empty so pipelines stay safe to parse:
roboflow --json project get nonexistent 2>error.json
echo $? # 3
cat error.json
# {"error": {"message": "Project 'nonexistent' not found", "hint": "Run 'roboflow project list' to see your projects."}}SDK exceptions
The Python SDK raises Python exceptions on failure. The most common types you'll encounter:
RuntimeError
Operation is logically invalid — e.g., calling restore() on a project that isn't in Trash, or training on a version that hasn't been generated.
ValueError
A passed argument is malformed — e.g., an unrecognized model_format for Version.download().
roboflow.adapters.rfapi.RoboflowError
The REST API returned a non-2xx response. The exception's string contains the server's error body.
roboflow.adapters.deploymentapi.DeploymentApiError
Equivalent to RoboflowError for the dedicated-deployments service.
requests.exceptions.HTTPError / ConnectionError
Network-level failures (DNS, TLS, timeout).
Rule of thumb: catch RuntimeError for logical issues, RoboflowError for server-side rejections, and let everything else bubble.
See Logging and Debugging for how to inspect the underlying HTTP request when an exception isn't enough.
REST API status codes
The REST API uses standard HTTP status codes. Roboflow-specific behavior:
200
Success. Response body is JSON.
204
Success, no body (used for some PATCH / DELETE endpoints).
400
Malformed request — missing required field, bad shape, invalid value.
401
Authentication failure. Either no api_key, an invalid one, or a key that lacks the required scope for the operation.
402
Payment required. The workspace's plan does not support the requested operation. For inference, this means the model or architecture is only available on a credit-based plan, or the workspace's monthly Hosted API inference quota has been reached. The response body includes an AccessException error type.
403
Forbidden. The key authenticated but doesn't have access to the target workspace or resource.
404
Not found. The workspace, project, version, workflow, or other resource doesn't exist (or isn't visible to your key).
409
Conflict. The resource exists in a state that prevents the requested operation (for example, restoring a version whose parent project is also in Trash).
423
Locked. Workspace billing is paused — see the response body for the reason.
429
Rate limited. Slow down and retry with exponential backoff.
5xx
Server error. Safe to retry with backoff.
Standard error body
Errors return JSON with at least a top-level error field:
Some endpoints also include a hint or a structured error object — see the per-endpoint documentation under REST API for specifics.
Required scopes
API keys carry per-resource scopes. A 401 from a write operation often means the key doesn't have the corresponding *:update or *:write scope, even if it can read the resource. See Scoped API Keys for the scope reference.
Cross-tool error mapping
Missing / invalid API key
2
RoboflowError ("401")
401
Resource not found
3
RoboflowError ("404") / RuntimeError
404
Plan limitation / quota exceeded
1
RoboflowError ("402")
402
Bad input / malformed request
1
ValueError / RoboflowError ("400")
400
Server error / transient
1
RoboflowError ("5xx")
5xx
Use this table when wiring retries: a 2 / 401 should never be retried automatically (the key won't get more valid), a 3 / 404 should never be retried, but a 1 from a 5xx response is a candidate for retry with backoff.
Last updated
Was this helpful?