Error handling#

Errors#

Error

errorCode

HTTP

Meaning

SQL_ERROR_INVALID_QUERY

INVALID_ARGUMENT

400

The query was rejected, for example for bad syntax, an unknown table or column, a disallowed function, or a missing dataset_rid filter. parameters.detail says why.

SQL_ERROR_RESULT_SIZE_EXCEEDED

INVALID_ARGUMENT

400

The result exceeded the 1 GB result size limit. Add a LIMIT, narrow the filters, or use export.

SQL_ERROR_QUERY_TIMEOUT

INVALID_ARGUMENT

400

The query timed out before completing. Add time bounds, channel filters, or tag filters to reduce the data scanned.

SQL_ERROR_EXPORT_NOT_SUPPORTED_FOR_BACKEND

INVALID_ARGUMENT

400

Export was called on a query that reads only the system tables provided for Postgres clients, such as information_schema.tables.

SQL_ERROR_UNAUTHENTICATED

UNAUTHORIZED

401

The request could not be authenticated. A missing or invalid API key returns a 401 without this error in the body.

SQL_ERROR_PERMISSION_DENIED

PERMISSION_DENIED

403

You don’t have view access to the workspace named in workspace_rid.

SQL_ERROR_DATASETS_NOT_FOUND

NOT_FOUND

404

One or more requested datasets don’t exist in the given workspace, or you can’t read them.

SQL_ERROR_DATA_NOT_FOUND_FOR_TYPE

NOT_FOUND

404

No data was found for one or more of the referenced datasets.

SQL_ERROR_RESOURCE_EXHAUSTED

429

The query exceeded a resource limit: the organization’s request rate, a memory limit, or the service’s capacity at that moment.

SQL_ERROR_EXECUTION_FAILED

INTERNAL

500

An unexpected internal error occurred during execution.

SQL_ERROR_QUERY_SCOPE_TOO_LARGE

INTERNAL

500

The query spans more datasets than can be planned at once. Add a dataset_rid or tag filter to narrow the datasets, or split the query.

SQL_ERROR_QUERY_CANCELLED

INTERNAL

500

The query was cancelled before it completed.

SQL_ERROR_EXPORT_NOT_CONFIGURED

FAILED_PRECONDITION

500

Export is not configured for this deployment.

Requests made with the same API key are also throttled before they reach the SQL service. Going over returns 429 with a plain-text body and a Retry-After header.

Request validation happens first#

A field that violates its constraints is rejected before the query reaches the planner: a missing workspace_rid, a query over 100,000 characters, or parquet_options on a CSV export. Those failures carry INVALID_ARGUMENT with the name ValidationNominalIo:ConstraintViolation and an empty parameters map.

That is a different failure from SQL_ERROR_INVALID_QUERY, which means your SQL was parsed and then rejected. The distinction tells you where to look: the request body, or the query text.

Error response schema#

Most errors serialize as a JSON object with the code, a name identifying what failed, a correlation id, and a parameters map. Querying a column that doesn’t exist returns:

{
  "errorCode": "INVALID_ARGUMENT",
  "errorName": "NominalSqlV1:SqlErrorInvalidQuery",
  "errorInstanceId": "942263b0-a664-4f4b-a249-066b02f20371",
  "parameters": {
    "detail": "From line 1, column 8 to line 1, column 11: Column 'nope' not found in any table",
    "sqlQueryId": "84d7919a-dae5-499f-a938-0d0bcf25c81b"
  }
}

Three details are worth knowing when you’re debugging:

  • Read parameters.detail first. On validation failures it carries the specific reason, with line and column positions into your query. errorName only tells you the category.

  • errorName tells you which layer rejected the request. NominalSqlV1:SqlErrorInvalidQuery and its siblings come from the SQL layer, and carry a sqlQueryId you can quote in a bug report. A bare Default:InvalidArgument with an empty parameters map means the request body never parsed at all.

  • RESOURCE_EXHAUSTED is shaped differently. It returns HTTP 429 with a body containing only parameters, and no errorCode or errorName, because there is no equivalent code in the serialization format the other errors use. Don’t parse it the same way.

Next steps#