Error Codes

NodeDB uses NodeDbError — a struct with numeric ErrorCode, human-readable message, machine-matchable ErrorDetails, and optional chained cause.

Error Categories

Code RangeCategoryExamples
1000–1099Write pathConstraint violation, deadline
1100–1199Read pathCollection not found, database not found
1200–1299QueryPlan error, undefined function
1300–1399EngineArray engine error
1400–1499Quota and overloadQuota exceeded, server overload
1500–1599CloneClone depth exceeded
1600–1699Move tenantDrain timeout, already at target
1700–1799MirrorMirror read-only
1800–1899BackupTenant or key mismatch
2000–2099AuthAuthorization denied, tenant limits
3000–3099SyncDelta rejected, sync error
4000–4299StorageSegment corrupted, WAL error, codec error
5000–5099ConfigBad request, invalid config
6000–6099ClusterNo leader, node unreachable
7000–7099MemoryMemory exhausted
8000–8099EncryptionKey error, decrypt failure
9000–9099InternalUnexpected internal error

Common Errors

ErrorCodeResolution
COLLECTION_NOT_FOUND1100Check collection name
TYPE_MISMATCH1020Check data types in query
CONSTRAINT_VIOLATION1000Duplicate key on plain INSERT maps to SQLSTATE 23505 (unique_violation). Use UPSERT or INSERT ... ON CONFLICT DO NOTHING / DO UPDATE for non-error semantics.
DEADLINE_EXCEEDED1002Query took too long
INSUFFICIENT_BALANCE1022Not enough for TRANSFER
OVERFLOW1021i64 overflow on INCR
AUTHORIZATION_DENIED2000Check RBAC grants
SYNC_DELTA_REJECTED3001CRDT sync constraint failed

Database Boundary Errors

ErrorCodeResolution
DATABASE_NOT_FOUND1110Verify database name; check SHOW DATABASES
CANNOT_DROP_DEFAULT_DATABASE1710The default database is reserved; drop user databases instead

Quota and Overload Errors (1400–1499)

ErrorCodeResolution
QUOTA_OVERCOMMIT1400Sum of tenant quotas exceeds database quota, or database quota exceeds global; rebalance quotas
TENANT_QUOTA_EXCEEDED1401Tenant's rate/concurrency/memory limit exhausted; reduce load or raise quota via ALTER TENANT … IN DATABASE … SET QUOTA
DATABASE_QUOTA_EXCEEDED1402Database's rate/concurrency/memory limit exhausted; reduce load or raise quota via ALTER DATABASE … SET QUOTA
SERVER_OVERLOAD1403A dispatch queue is at capacity. Nothing ran. Retry with exponential backoff. See Transient capacity refusal.
TENANT_VECTOR_DIM_EXCEEDED2010Vector embedding dimensionality exceeds tenant's max_vector_dim; reduce dimensionality or raise quota
TENANT_GRAPH_DEPTH_EXCEEDED2011Graph traversal depth exceeds tenant's max_graph_depth; reduce traversal depth or raise quota

A login past the cluster session cap (max_active_sessions) answers BAD_REQUEST (5001). Close idle sessions or raise the cap.

Transient capacity refusal (SERVER_OVERLOAD)

The bridge dispatcher refuses a request when one of its capacity limits is full:

ScopeLimit
tenant_inflightThe tenant holds its fair share of in-flight requests. The share is the total queue capacity divided by the tenants with requests in flight, and at least two.
database_suspendedThe database's queue on the target core holds 95% or more of its fair share.
queue_fullThe target core's queue holds its full capacity.

The refusal is transient and retryable:

  • The server enqueued nothing and ran nothing. Resending the same request is safe.
  • Retry with exponential backoff. The same request succeeds once in-flight requests finish and free capacity.
  • The error message names the scope and its counts.

Each protocol answers the refusal with one class:

ProtocolAnswer
pgwireSQLSTATE 57P03 (cannot_connect_now)
NativeError frame with SQLSTATE 57P03 and ndb_code 1403
HTTP503 Service Unavailable, Retry-After: 1, body code NDB-1403
RESPBUSY error prefix

57P03 is distinct from XX000 (internal error). A client backs off and retries on 57P03, and aborts on XX000. A collection that is draining and a migration in progress also answer 57P03, with the same retry contract.

Two counters track the refusal:

  • nodedb_dispatch_capacity_busy_total{scope} counts each refusal by scope, including the ones the server waits out before it answers. It measures dispatch pressure.
  • nodedb_server_overload_responses_total{protocol} counts each overload answer a client receives. It measures client impact.

A gap between the two means the server absorbs the pressure. See Monitoring.

A cross-shard (Calvin) transaction does not fail on this refusal. The Calvin scheduler holds the refused transaction with its locks and re-sends it once capacity frees. nodedb_calvin_dispatch_deferred_total{vshard} counts those deferrals.

Database Clone Errors (1500–1599)

ErrorCodeResolution
CLONE_DEPTH_EXCEEDED1500Clone lineage exceeds MAX_CLONE_DEPTH = 8; promote source clone to materialize and flatten lineage
CLONE_DEPENDENCY1502Source database has dependent clones; DROP clones first or use DROP DATABASE source FORCE to trigger materialization
CANNOT_CLONE_MIRROR1501Mirrors are read-only and create ambiguous bitemporal lineage; PROMOTE the mirror first, then clone

Database Mirror Errors (1700–1799)

ErrorCodeSQLSTATEResolution
MIRROR_READ_ONLY170025006Mirror is read-only until promoted; use ALTER DATABASE <mirror> PROMOTE to switch to writable mode
STALE_READ_NOT_LEADER170155P03Strong consistency requested on a mirror (which is stale); use BoundedStaleness or Eventual consistency, or connect to the source database for strong reads

A lagging or disconnected mirror is a mirror status (Degraded, Disconnected), not an error. Queries against it keep the codes above.

Move Tenant Errors

ErrorCodeResolution
MOVE_TENANT_ALREADY_AT_TARGET1604Tenant already moved to target database; re-issuing is idempotent (safe to retry)

Session Lifecycle Errors

Session lifecycle conditions carry no dedicated code. Each answers the code and SQLSTATE below, and the message names the condition.

ConditionCodeSQLSTATEResolution
Session closed: user account droppedBAD_REQUEST (5001)42601Reconnect with a valid user
Session closed: idle timeout exceededBAD_REQUEST (5001)42601Reconnect; keep the session active within idle_session_timeout_secs
Session closed by KILL SESSIONBAD_REQUEST (5001)42601Reconnect
Session closed: OIDC token expiredAUTH_EXPIRED (2001)28000Re-authenticate with a fresh token
KILL SESSION names an unknown session IDUNDEFINED_OBJECT (1111)42704Check active session IDs with SHOW SESSIONS

Error Construction

Errors are created via constructors: NodeDbError::storage("detail"), NodeDbError::collection_not_found("users"), etc.