{
"error": {
"code": "QUERY_TIMEOUT",
"message": "Query exceeded the configured timeout",
"details": { ... }
}
}
Authentication errors (HTTP 401, 403)
| Code | Meaning | Fix |
|---|---|---|
UNAUTHENTICATED | No or invalid token | Check the Authorization header |
TOKEN_EXPIRED | Token has expired | Generate a new token |
TOKEN_REVOKED | Token was revoked | Generate a new token |
PERMISSION_DENIED | Token can’t perform this action | Check the token’s role/scope |
Request errors (HTTP 400)
| Code | Meaning | Fix |
|---|---|---|
INVALID_REQUEST | Request body is malformed JSON or missing required fields | Check the request format |
INVALID_QUERY | SQL has a syntax error | Fix the SQL |
CLUSTER_NOT_FOUND | Named cluster doesn’t exist | Check the cluster name |
CATALOG_NOT_FOUND | Named catalog doesn’t exist or isn’t attached to the cluster | Check catalog name and cluster attachment |
SCHEMA_NOT_FOUND | Schema isn’t in the catalog | Refresh the catalog or check the name |
TABLE_NOT_FOUND | Table doesn’t exist in the schema | Check the table name |
INVALID_PARAMETER | Query parameter binding failed | Check parameter types and names |
Query lifecycle errors
| Code | Meaning | What it means |
|---|---|---|
QUERY_CANCELLED | Query was cancelled via POST .../cancel | Expected after a cancel call |
QUERY_TIMEOUT | Query exceeded the configured timeout | Either tune the query or raise the timeout |
QUERY_FAILED | Query failed during execution | Read details for the underlying error |
RESULT_EXPIRED | Query results no longer available | Results retention typically 24h; rerun the query |
RESULT_TOO_LARGE | Result set exceeds the max response size | Use pagination or streaming |
Resource errors (HTTP 503)
| Code | Meaning | Fix |
|---|---|---|
CLUSTER_SUSPENDED | Cluster is suspended | Will auto-resume if configured; otherwise resume manually |
CLUSTER_PROVISIONING | Cluster is being created | Wait for cluster to become Running |
CLUSTER_UNAVAILABLE | Cluster has an error preventing queries | Check Compute Plane → cluster status |
Rate limiting (HTTP 429)
| Code | Meaning | Fix |
|---|---|---|
RATE_LIMITED | Too many requests | Honor Retry-After header; reduce request rate |
CONCURRENT_LIMIT | Too many concurrent queries on this cluster | Wait or increase cluster size |
Server errors (HTTP 5xx)
| Code | Meaning | Fix |
|---|---|---|
INTERNAL_ERROR | Unexpected server error | Retry; if persistent, contact support with the Query ID |
SERVICE_UNAVAILABLE | Backend is temporarily unavailable | Retry with backoff |
Error handling pattern
A robust client handles these categories distinctly:import time
import httpx
# The endpoint requires HTTP/2 - pip install "httpx[http2]"
client = httpx.Client(http2=True)
def call_with_retry(method, url, **kwargs):
backoff = 1
for attempt in range(5):
r = client.request(method, url, **kwargs)
if r.status_code == 200:
return r.json()
error = r.json().get("error", {})
code = error.get("code")
# Retry transient errors
if r.status_code in (429, 503) or code in ("INTERNAL_ERROR", "SERVICE_UNAVAILABLE"):
retry_after = int(r.headers.get("Retry-After", backoff))
time.sleep(retry_after)
backoff *= 2
continue
# Don't retry permanent errors
raise RuntimeError(f"{r.status_code} {code}: {error.get('message')}")
raise RuntimeError("Exhausted retries")