Errors and help

Every refusal from LakehouseBox says what went wrong and what to do next. This page explains how to read one, lists the errors people and agents meet most and what each one wants, and says where to look when something seems broken. Every error code a public route can answer is in the index at the end.

How an error looks

The API answers every failure with one JSON object:

{"error": {
  "code": "quota_exceeded",
  "message": "This organisation is over its private storage limit: 5,400,000,000 of 5,368,709,120 bytes.",
  "limit_value": 5368709120, "current": 5400000000, "headroom": 0,
  "remedy": "… what frees space, or who raises the limit",
  "request_id": "…"}}
  • code is stable: match on it, never on message.
  • remedy, when present, is the next step. Act on it rather than retrying the same request.
  • request_id is always there. Quote it when you write to us.
  • Some errors add fields that help: field (which input was wrong), limit, current and available (a limit and where you stand), retry_after_seconds (when to try again, also sent as Retry-After), attempts_left, candidates (the ids behind an ambiguous name), can_grant (who can give you access).
  • An unexpected failure is a 500 with the same shape and a request_id.

When the caller is an lhbox older than the one published, a refusal also carries cli_outdated with the published version and how to update: an option the docs describe may be newer than your CLI. lhbox update installs the current one.

The lhbox CLI prints the same object (on stderr) and ends with an exit code that says what kind of failure it was:

exit meaning what to do
0 ok
1 the input is wrong fix the values; never retry unchanged
2 a real limit or conflict a quota or a 409: change the plan, free space, or ask for a higher limit
3 authentication the key is missing, wrong or revoked: lhbox whoami, then lhbox login
4 not found no such project, catalog, namespace or table (or none you can see)
5 our side or the network safe to retry with backoff
6 the command line is malformed fix the command (lhbox <command> --help); never retry

The errors you will meet most

code HTTP what it means what to do
invalid_api_key, api_key_revoked, unauthorized 401 the key is wrong, revoked, or missing lhbox whoami names the key in use; lhbox login connects this machine again
reauth_required 401 a sensitive change from a browser session that signed in more than 10 minutes ago sign in again on the account page and retry; an API key is never asked
forbidden 403 you hold read where write is needed, or none at all can_grant names who can give you access; ask them
insufficient_role 403 an admin's action asked by a member ask an admin of the organisation
org_policy_forbids 403 the organisation's policy keeps this to admins (publishing, connecting agents) ask an admin
warehouse_not_found, table_not_found, namespace_not_found 404 no such catalog, namespace or table, or one you cannot see lhbox catalog list, lhbox table list; a name close to yours comes back as did_you_mean where the MCP tools answer
ambiguous_name 409 two catalogs share that name use one of the ids in candidates
quota_exceeded 409 the organisation is over its storage limit reading still works; free space, or write to us and we raise it
limit_exceeded 409 a count limit, such as catalogs per project lhbox usage shows each limit and your headroom
idempotency_key_reused 409 the same --idempotency-key was sent with a different request use a new key for a new request
creation_in_progress 409 the same catalog is being created right now wait the Retry-After and look again
confirmation_required 400 a destructive command without its confirmation repeat it with --confirm (or --yes); confirm_with names the value expected
terms_required 400 the Terms were not accepted accept them (--accept-terms, or the account page)
rate_limited 429 too many requests too fast wait retry_after_seconds; sooner is refused without running
busy 429 the shared query queue is full wait retry_after_seconds, or run the query in your own DuckDB (lhbox duckdb)
query_timeout 408 a server-side query ran past its 20 seconds filter and aggregate more in SQL, or run it in your own DuckDB, which has no time limit
store_timeout, query_unavailable, other 5xx 5xx our side retry with backoff; if it persists, check the status page and write to us with the request_id

Two refusals come from your engine rather than from the API:

  • A commit conflict (409 from the catalog, CommitFailedException in PyIceberg and Spark). Iceberg commits are optimistic: when someone else committed to the table first, including the catalog's own maintenance, your commit is refused and should be retried on the new version. Spark retries a few times on its own; a script that writes with PyIceberg should catch the conflict and retry.
  • DuckDB: "attached in read-only mode". The catalog was attached with s3://<bucket>/ instead of the bare bucket name. lhbox duckdb and lhbox connect --engine duckdb print the right ATTACH. More gotchas per engine: Engines.

Before you write to us

  1. lhbox doctor checks this machine end to end: the key, the catalog, the engine recipe (--write-probe also writes and deletes one empty file, the one check that sees a refused write).
  2. lhbox whoami says which key and organisation are in use; lhbox usage lists every limit with your headroom.
  3. lhbox update when the CLI says it is out of date.
  4. The status page shows whether signing up, logging in, connecting an agent, reading and writing data, the MCP server and the website work right now, checked every 5 minutes from outside our servers.

Getting help

Write to hello@lakehousebox.com with the command or request, the request_id and what you expected. The first answer comes within 2 business days on every plan, within 1 business day on Enterprise (support). Security reports go to the same address (security.txt).

Every error code

Built from the API reference: each code a public route documents, its HTTP status and the routes that answer it (what each means on that route is there).

codeHTTPanswered by
access_denied403POST /oauth/register
account_deleted401POST /v1/tokens
agents_md_changed409PUT /v1/warehouses/{warehouse_id}/agents-md
already_exists409POST /v1/signup/start, POST /v1/signup/verify, POST /v1/projects, POST /v1/warehouses, POST /v1/warehouses/{warehouse_id}/restore, POST /v1/warehouses/{warehouse_id}/uploaders and 3 more
ambiguous_name409GET /v1/warehouses/{warehouse_id}, PATCH /v1/warehouses/{warehouse_id}, POST /v1/warehouses/{warehouse_id}/measure, POST /v1/warehouses/{warehouse_id}/restore, POST /v1/warehouses/{warehouse_id}/rotate, GET /v1/sinks/{sink_id} and 2 more
anonymous_not_enabled403POST /v1/agent/identity, POST /v1/oauth/authorize/set-up
api_key_not_found404DELETE /v1/api-keys/{key_id}
api_key_revoked401POST /v1/tokens
authorization_pending400POST /v1/auth/device/token
bad_name400POST /v1/warehouses/{warehouse_id}/uploaders, POST /v1/sinks
batch_too_large413POST /v1/sinks/{sink_id}
body_too_large413POST /d/{token}, POST /v1/sinks/{sink_id}/test
bucket_leftover_from_deletion409POST /v1/warehouses
busy429GET /v1/object, POST /v1/query
catalog_error502POST /v1/tables, PATCH /v1/table, DELETE /v1/table, DELETE /v1/namespace, POST /v1/credentials
catalog_grant_held409PUT /v1/warehouses/{warehouse_id}/grants/{principal_id}
catalog_unavailable502POST /v1/query
claim_gone409POST /v1/agent/identity/claim
code_expired410POST /v1/signup/verify, POST /v1/auth/google/link
code_not_confirmed400POST /v1/auth/device/approve
column_not_found400PATCH /v1/table
confirmation_required400DELETE /v1/warehouses/{warehouse_id}, POST /v1/warehouses/{warehouse_id}/public, DELETE /v1/me
creation_in_progress409POST /v1/warehouses
creator_revoked403POST /v1/orgs/{org_id}/tokens
delete_in_progress409DELETE /v1/warehouses/{warehouse_id}, DELETE /v1/me
device_code_not_found404GET /v1/auth/device/pending, POST /v1/auth/device/approve, GET /v1/auth/device/status
disposable_email400POST /v1/signup/start, POST /v1/signup/verify, POST /v1/auth/signup, POST /v1/auth/google/callback
dns_unavailable503POST /v1/orgs/{org_id}/domains/{domain}/verify
domain_claimed409POST /v1/orgs/{org_id}/domains/{domain}/verify
domain_not_found404POST /v1/orgs/{org_id}/domains/{domain}/verify, DELETE /v1/orgs/{org_id}/domains/{domain}
domain_not_verified409POST /v1/orgs/{org_id}/domains/{domain}/verify
email_code_required401POST /v1/auth/google/callback
email_not_verified403, 409POST /v1/auth/google/callback, PUT /v1/me/news
enterprise_feature403PUT /v1/warehouses/{warehouse_id}/grants/{principal_id}
forbidden403PATCH /v1/warehouses/{warehouse_id}, PUT /v1/warehouses/{warehouse_id}/grants/{principal_id}, DELETE /v1/warehouses/{warehouse_id}/grants/{principal_id}, DELETE /v1/warehouses/{warehouse_id}, POST /v1/warehouses/{warehouse_id}/restore, POST /v1/warehouses/{warehouse_id}/uploaders and 34 more
google_unavailable502POST /v1/auth/google/callback
grant_not_found404DELETE /v1/warehouses/{warehouse_id}/grants/{principal_id}
handle_taken409POST /v1/signup/start, POST /v1/auth/signup, POST /v1/onboard
idempotency_key_reused409POST /v1/projects
identity_conflict409POST /v1/auth/google/callback
implicit_grant409PUT /v1/warehouses/{warehouse_id}/grants/{principal_id}, DELETE /v1/warehouses/{warehouse_id}/grants/{principal_id}
index_not_found404GET /v1/indexes/{index_id}, DELETE /v1/indexes/{index_id}
insufficient_role403PATCH /v1/orgs/{org_id}, PATCH /v1/orgs/{org_id}/policy, DELETE /v1/orgs/{org_id}/members/{member_id}, POST /v1/orgs/{org_id}/invitations, GET /v1/orgs/{org_id}/invitations, DELETE /v1/orgs/{org_id}/invitations/{invitation_id} and 3 more
insufficient_scope403GET /v1/object, POST /v1/query
invalid_api_key401POST /v1/tokens
invalid_client400, 401GET /oauth/authorize, POST /oauth/token
invalid_client_metadata400POST /oauth/register
invalid_code401POST /v1/signup/verify, POST /v1/auth/google/link
invalid_credentials401POST /v1/auth/reauth, POST /v1/auth/passkeys/register/start, POST /v1/auth/mfa/totp/start, POST /v1/auth/mfa/totp/disable, DELETE /v1/me
invalid_device_token401POST /d/{token}
invalid_enrol_token401POST /v1/auth/mfa/enrol/start, POST /v1/auth/mfa/enrol/confirm
invalid_extractors400POST /v1/indexes
invalid_field400PATCH /v1/warehouses/{warehouse_id}, PATCH /v1/orgs/{org_id}/policy
invalid_files_prefix400POST /v1/warehouses/{warehouse_id}/public
invalid_google_code401POST /v1/auth/google/callback
invalid_google_token401POST /v1/auth/google/link
invalid_id_token401POST /v1/auth/google/callback
invalid_key400, 401POST /v1/sinks/{sink_id}, GET /v1/warehouses/{warehouse_id}/blobs/presign, POST /v1/warehouses/{warehouse_id}/blobs/upload, DELETE /v1/warehouses/{warehouse_id}/blobs, GET /v1/object
invalid_login401POST /v1/auth/login, POST /v1/auth/password/change
invalid_login_token401POST /v1/auth/password/set, POST /v1/auth/password/reset
invalid_mfa_code400, 401POST /v1/auth/login, POST /v1/auth/login/mfa, POST /v1/auth/mfa/enrol/confirm, POST /v1/auth/reauth, POST /v1/auth/passkeys/register/finish, POST /v1/auth/mfa/totp/confirm and 3 more
invalid_mfa_token401POST /v1/auth/login/mfa, POST /v1/auth/login/passkey/start
invalid_name400POST /v1/warehouses
invalid_passkey400, 401POST /v1/auth/login/mfa, POST /v1/auth/login/passkey, POST /v1/auth/passkeys/register/finish
invalid_prefix400GET /v1/warehouses/{warehouse_id}/blobs
invalid_refresh_token401POST /v1/auth/refresh
invalid_request400GET /oauth/authorize, POST /oauth/token
invalid_setup_token401POST /v1/setup
invalid_state400POST /v1/auth/google/callback
invalid_token400POST /v1/news/unsubscribe
invalid_value400POST /v1/signup/start, POST /v1/warehouses, PATCH /v1/warehouses/{warehouse_id}, PUT /v1/warehouses/{warehouse_id}/grants/{principal_id}, DELETE /v1/warehouses/{warehouse_id}, PATCH /v1/sinks/{sink_id} and 14 more
invitation_accepted409DELETE /v1/orgs/{org_id}/invitations/{invitation_id}
invitation_expired410POST /v1/orgs/invitations/accept
invitation_for_someone_else403POST /v1/orgs/invitations/accept
invitation_not_found404DELETE /v1/orgs/{org_id}/invitations/{invitation_id}, POST /v1/orgs/invitations/accept
inviter_unknown403POST /v1/orgs/{org_id}/invitations
inviter_unverified403POST /v1/orgs/{org_id}/invitations
last_admin409PATCH /v1/orgs/{org_id}/members/{member_id}, DELETE /v1/orgs/{org_id}/members/{member_id}, DELETE /v1/me
left_organisation403POST /v1/orgs/{org_id}/join
limit_exceeded409POST /v1/warehouses, POST /v1/warehouses/{warehouse_id}/restore, POST /v1/warehouses/{warehouse_id}/uploaders
mail_error502POST /v1/signup/start, POST /v1/auth/signup
member_not_found404PATCH /v1/orgs/{org_id}/members/{member_id}, DELETE /v1/orgs/{org_id}/members/{member_id}
mfa_already_enabled409POST /v1/auth/mfa/enrol/start, POST /v1/auth/mfa/enrol/confirm, POST /v1/auth/mfa/totp/start, POST /v1/auth/mfa/totp/confirm
mfa_code_required401POST /v1/auth/reauth, POST /v1/auth/passkeys/register/start, POST /v1/auth/passkeys/register/finish, DELETE /v1/me
mfa_enrolment_required401, 403POST /v1/tokens, POST /v1/auth/login
mfa_not_enabled409POST /v1/auth/mfa/totp/disable, POST /v1/auth/mfa/backup-codes
mfa_not_started404POST /v1/auth/mfa/enrol/confirm, POST /v1/auth/mfa/totp/confirm
mfa_required401POST /v1/auth/login, POST /v1/auth/google/callback
mfa_required_by_policy409DELETE /v1/auth/passkeys/{passkey_id}, POST /v1/auth/mfa/totp/disable
mfa_unavailable503POST /v1/auth/login/mfa
missing_field400PATCH /v1/warehouses/{warehouse_id}, POST /v1/tables, PATCH /v1/table, DELETE /v1/table, DELETE /v1/namespace, POST /v1/query and 1 more
name_reserved_until_cdn_purge409POST /v1/warehouses
name_reserved_until_teardown409POST /v1/warehouses
name_too_long_for_bucket400POST /v1/warehouses
namespace_not_empty409DELETE /v1/namespace
namespace_not_found404PUT /v1/warehouses/{warehouse_id}/grants/{principal_id}, GET /v1/tables, GET /v1/table, PATCH /v1/table, DELETE /v1/table, DELETE /v1/namespace and 1 more
news_disabled409PUT /v1/me/news
no_domain_offer404POST /v1/orgs/{org_id}/join
no_password_set409POST /v1/auth/password/change
no_pending_code404POST /v1/auth/google/link
no_pending_signup404POST /v1/signup/verify
no_verified_domain400PATCH /v1/orgs/{org_id}
not_a_person403POST /v1/auth/reauth, GET /v1/auth/passkeys, POST /v1/auth/mfa/totp/start, POST /v1/terms/accept, PUT /v1/me/news
not_an_array400POST /v1/sinks/{sink_id}
not_deleted409POST /v1/warehouses/{warehouse_id}/restore
not_found404POST /v1/sinks, GET /v1/object, POST /v1/query, GET /v1/auth/google/start, POST /v1/auth/google/callback
not_restorable409POST /v1/warehouses/{warehouse_id}/restore
not_unclaimed409POST /v1/agent/identity/claim
oauth_request_decided410GET /v1/oauth/authorize/pending
oauth_request_expired410GET /v1/oauth/authorize/pending, POST /v1/oauth/authorize/decision, GET /v1/oauth/authorize/set-up, POST /v1/oauth/authorize/set-up
oauth_request_not_found404GET /v1/oauth/authorize/pending, POST /v1/oauth/authorize/decision, GET /v1/oauth/authorize/set-up, POST /v1/oauth/authorize/set-up
org_not_found404POST /v1/projects, GET /v1/orgs/{org_id}/policy, GET /v1/audit
org_policy_forbids403POST /v1/warehouses/{warehouse_id}/public, DELETE /v1/warehouses/{warehouse_id}/public, POST /v1/orgs/{org_id}/tokens, POST /v1/auth/device/approve, POST /v1/auth/device/token, POST /v1/oauth/authorize/decision and 1 more
org_required400, 409POST /v1/projects, GET /v1/auth/device/pending, POST /v1/auth/device/approve, GET /v1/oauth/authorize/pending, POST /v1/oauth/authorize/decision
origin_not_allowed403GET /v1/auth/google/start, POST /v1/auth/login/passkey, POST /v1/auth/refresh, GET /v1/auth/accounts
passkey_exists409POST /v1/auth/passkeys/register/finish
passkey_limit409POST /v1/auth/passkeys/register/start, POST /v1/auth/passkeys/register/finish
passkey_not_found404DELETE /v1/auth/passkeys/{passkey_id}
passkeys_disabled403POST /v1/auth/login/passkey/start
password_required400, 409POST /v1/auth/reauth, POST /v1/auth/passkeys/register/start, POST /v1/setup, DELETE /v1/me
password_too_short400POST /v1/auth/password/set
person_required403POST /v1/warehouses/{warehouse_id}/public
principal_inactive409PUT /v1/warehouses/{warehouse_id}/grants/{principal_id}
principal_not_found404PUT /v1/warehouses/{warehouse_id}/grants/{principal_id}
principal_suspended403POST /v1/tokens, POST /v1/auth/login, POST /v1/auth/mfa/enrol/start, POST /v1/auth/login/passkey
project_not_found404POST /v1/warehouses, GET /v1/warehouses
provisioning503POST /v1/query, GET /v1/connection
public_catalog409DELETE /v1/table, DELETE /v1/namespace
public_catalog_ambiguous409GET /v1/public/{handle}/{catalog}/connection
public_catalog_not_found404GET /v1/public/{handle}/{catalog}/connection
public_mail_domain400POST /v1/orgs/{org_id}/domains
public_reader_unavailable503GET /v1/public/{handle}/{catalog}/connection
query_timeout408POST /v1/query
query_unavailable503GET /v1/object
quota_exceeded409POST /v1/warehouses, POST /v1/warehouses/{warehouse_id}/public, POST /v1/tables, POST /v1/credentials
rate_limited429POST /v1/tokens, POST /v1/signup/start, POST /v1/agent/identity, POST /v1/agent/identity/claim, GET /v1/handles/{handle}, POST /v1/warehouses/{warehouse_id}/measure and 26 more
reauth_required401POST /v1/warehouses/{warehouse_id}/rotate, POST /v1/warehouses/{warehouse_id}/uploaders, POST /v1/sinks, POST /v1/sinks/{sink_id}/device-token, POST /v1/orgs/{org_id}/tokens, POST /v1/auth/reauth and 3 more
recovery_retired410POST /v1/recover/start, POST /v1/recover/verify
refresh_raced401POST /v1/auth/refresh
registration_closed403POST /v1/signup/start, POST /v1/agent/identity, POST /v1/signup/verify, POST /v1/signup, POST /v1/auth/signup, POST /v1/auth/password/set and 2 more
schema_changed409PATCH /v1/table
service_auth_not_enabled400POST /v1/agent/identity
session_not_found404DELETE /v1/auth/sessions/{session_id}
session_required403POST /v1/auth/reauth, GET /v1/auth/passkeys, POST /v1/auth/passkeys/register/start, POST /v1/auth/mfa/totp/start, POST /v1/auth/mfa/totp/confirm, GET /v1/oauth/authorize/pending and 1 more
setup_done409POST /v1/setup
sink_disabled409POST /v1/sinks/{sink_id}, POST /d/{token}
sink_exists409POST /v1/sinks, POST /v1/indexes
sink_needs_read400POST /v1/orgs/{org_id}/tokens
sink_not_found404GET /v1/sinks/{sink_id}, DELETE /v1/sinks/{sink_id}, POST /v1/sinks/{sink_id}, POST /v1/sinks/{sink_id}/test, POST /v1/sinks/{sink_id}/device-token, DELETE /v1/sinks/{sink_id}/device-token and 2 more
storage_error502, 503POST /v1/warehouses, POST /v1/warehouses/{warehouse_id}/measure, PUT /v1/warehouses/{warehouse_id}/grants/{principal_id}, POST /v1/warehouses/{warehouse_id}/uploaders, POST /v1/sinks/{sink_id}, POST /d/{token} and 10 more
store_error502GET /v1/object
store_timeout504GET /v1/object
table_has_sinks409DELETE /v1/table, DELETE /v1/namespace
table_not_found404POST /v1/indexes, GET /v1/table, PATCH /v1/table, DELETE /v1/table, POST /v1/credentials
terms_required400POST /v1/signup/verify, POST /v1/auth/google/callback, POST /v1/oauth/authorize/set-up, POST /v1/onboard
terms_version_mismatch409POST /v1/terms/accept
token_expired410POST /v1/auth/password/set, POST /v1/auth/password/reset
token_not_found404GET /v1/orgs/{org_id}/tokens/{token_id}, PATCH /v1/orgs/{org_id}/tokens/{token_id}, DELETE /v1/orgs/{org_id}/tokens/{token_id}
too_large413PUT /v1/warehouses/{warehouse_id}/lifecycle, PUT /v1/warehouses/{warehouse_id}/agents-md
too_many_claims400POST /v1/orgs/{org_id}/domains
unauthorized401GET /v1/public/{handle}/{catalog}/connection
unclaimed_expired401POST /v1/agent/identity/claim
unreadable_body400POST /d/{token}, POST /v1/sinks/{sink_id}/test
unsupported_engine400GET /v1/connection
unsupported_media_type415POST /d/{token}, POST /v1/sinks/{sink_id}/test
unsupported_placement400POST /v1/projects
verification_required403POST /v1/signup
warehouse_deleted404DELETE /v1/warehouses/{warehouse_id}
warehouse_deleting404GET /v1/warehouses/{warehouse_id}
warehouse_not_found404GET /v1/warehouses/{warehouse_id}, PATCH /v1/warehouses/{warehouse_id}, POST /v1/warehouses/{warehouse_id}/measure, GET /v1/warehouses/{warehouse_id}/grants, DELETE /v1/warehouses/{warehouse_id}, POST /v1/warehouses/{warehouse_id}/restore and 25 more