General
Error Codes
Every error group and code the Rivet HTTP API and connection protocol can return.
Errors are identified by group and code. See Errors for the response format and Connect for how they arrive over a WebSocket connection.
The Status column shows the HTTP status the error is returned with. When the gateway and the control plane disagree, both are listed. Codes without a status use the default for where they were raised: 400 from the control plane and gateway, and 500 from inside the actor runtime, where the message is also replaced with a generic internal error unless the code is listed here with a status. Errors thrown by your own actor code with UserError use the user group with whatever code you supply, and always return 400.
Messages may contain placeholders in braces that are filled in at runtime. Match on group and code, not on message.
actor api auth config connection datacenter depot depot_kv engine envoy guard inspector message namespace napi pool protocol queue registry request runner runner_pool serverless_runner_pool sqlite topology ups user validation wasm ws
actor
Actor lifecycle, addressing, and actions.
| Code | Status | Message |
actor.aborted | 400 | Actor aborted |
actor.action_timed_out | 408 | Action timed out |
actor.destroying | | Actor is destroying. |
actor.dropped_reply | | Actor reply channel was dropped without a response. |
actor.duplicate_key | 409 | Actor key already in use. |
actor.input_too_large | | Actor input too large. |
actor.invalid_cursor | | The actor listing cursor is malformed. |
actor.invalid_include_destroyed | | The actor listing include_destroyed flag must be true or false. |
actor.invalid_key | | Actor key is invalid. |
actor.invalid_key_encoding | | Actor key is not in the canonical slash-separated form produced by serializeActorKey. |
actor.invalid_limit | | The actor listing limit must be an integer from 1 to 100. |
actor.invalid_listing | | Listing actors requires a name or actor IDs. |
actor.invalid_name | | Actor name is invalid. |
actor.invalid_operation | | Actor operation is invalid. |
actor.invalid_request | 400 | Invalid hibernatable websocket connection ID |
actor.js_callback_unavailable | | JavaScript callback unavailable |
actor.key_owned_elsewhere | | The actor key is owned by another datacenter. |
actor.key_too_large | | Key label too large. |
actor.kv_key_too_large | | A KV key is too large. |
actor.kv_response_too_large | | The KV response is too large. Read fewer keys per request. |
actor.kv_too_many_keys | | The KV request names too many keys. |
actor.method_not_allowed | 405 | Method not allowed |
actor.missing_input | | Actor input is missing. |
actor.not_configured | | Actor capability is not configured. |
actor.not_found | 404 | The actor does not exist or was destroyed. |
actor.not_ready | | Actor is not ready. |
actor.not_registered | | Actor factory is not registered. |
actor.overloaded | | Actor is overloaded. |
actor.panicked | | Actor task panicked. |
actor.shutdown_timeout | | Actor shutdown timed out. |
actor.starting | | Actor is starting. |
actor.stopping | | Actor is stopping. |
api
Malformed requests to the control plane.
| Code | Status | Message |
api.forbidden | 403 | Access denied |
api.internal_error | | An internal server error occurred |
api.not_found | 404 | The requested resource was not found |
api.unauthorized | 401 | Authentication required |
auth
Token validation and permissions.
| Code | Status | Message |
auth.insufficient_permissions | 403 | Insufficient permissions to access this resource. |
auth.invalid_token | 401 | Authentication token is invalid. |
auth.issuance_disabled | 403 (control plane), 503 (gateway) | JWT issuance is not enabled for this deployment. |
auth.issuance_unavailable | 503 | The server could not issue an authentication token because the signing service is temporarily unavailable. Retry the request. |
auth.token_expired | 401 | Authentication token has expired. |
auth.verification_unavailable | 503 | The server could not verify the authentication token because verification keys are temporarily unavailable. Retry the request. |
config
| Code | Status | Message |
config.endpoint_mismatch | | Endpoint mismatch. |
config.namespace_mismatch | | Namespace mismatch. |
connection
Actor connections opened through the connection protocol.
| Code | Status | Message |
connection.disconnect_failed | | Connection disconnect failed |
connection.not_configured | | Connection callback is not configured |
connection.not_found | | Connection was not found |
connection.not_hibernatable | | Connection is not hibernatable |
connection.restore_not_found | | Hibernatable connection restore target was not found |
datacenter
| Code | Status | Message |
datacenter.not_found | | The provided datacenter does not exist. |
depot
| Code | Status | Message |
depot.command_too_large | | The command exceeds the byte limit. |
depot.conflict | | The command conflicted with a concurrent change to the volume. |
depot.corrupt | | The volume's stored data failed a consistency check. |
depot.database_not_found | | Database was not found in this bucket branch. |
depot.fenced | | A newer owner holds the volume; the command was not applied by this owner. |
depot.head_fence_mismatch | | SQLite head fence mismatch. |
depot.legacy_layout | | The actor volume predates the /actor layout and must be reinitialized. |
depot.overloaded | | The storage host refused the command; retry after the hinted delay. |
depot.quota_exceeded | | Not enough space left in Depot. |
depot.read_interrupted | | The storage read was interrupted; retry after the hinted delay. |
depot.request_deadline_exceeded | | The command deadline elapsed; its outcome may be unknown. |
depot.routing_unavailable | | No tablet maintainer route is available. |
depot.scope_revoked | | The caller scope ended; submitted work may still complete. |
depot.storage_unavailable | | Depot storage is not available in this build. |
depot.unavailable | | The storage host could not finish the command; its outcome may be unknown. |
depot.unknown_command | | The maintainer does not recognize this command. |
depot.volume_deleted | | The KV database volume was deleted. |
depot.volume_not_found | | The KV database volume does not exist. |
depot_kv
| Code | Status | Message |
depot_kv.closed | | The engine is closed. |
depot_kv.conflict | | The transaction conflicts with a later write. |
depot_kv.corrupt | | Stored data failed its integrity checks. |
depot_kv.failed | | The write failed. |
depot_kv.invalid_key | | The key or range is invalid. |
depot_kv.overloaded | | The engine commit queue is full. |
depot_kv.storage | | A block device read failed. |
depot_kv.too_large | | The transaction exceeds a configured limit. |
depot_kv.too_old | | The snapshot is too old. |
engine
| Code | Status | Message |
engine.binary_not_found | | Engine binary was not found. |
engine.binary_unavailable | | Engine binary is unavailable. |
engine.checksum_mismatch | | Engine binary checksum mismatch. |
engine.download_failed | | Engine binary download failed. |
engine.health_check_failed | | Engine health check failed. |
engine.incompatible_engine | | An incompatible engine is already running on the endpoint. |
engine.invalid_endpoint | | Engine endpoint is invalid. |
engine.missing_pid | | Engine process is missing a pid. |
engine.not_ready | | Engine did not become ready. |
engine.port_occupied | | Engine port is occupied by a different runtime. |
envoy
Node connections, and validation of namespace and pool names.
| Code | Status | Message |
envoy.connect_overloaded | | Too many runners are connecting at once. Retry after the hint. |
envoy.connect_unavailable | | Storage could not register the runner yet. Retry after the hint. |
envoy.invalid_namespace_name | | Namespace name is invalid. |
envoy.invalid_pool_name | | Pool name is invalid. |
envoy.malformed_message | | The message could not be decoded. |
guard
The gateway that routes requests to actors, including request parsing, rate limits, and timeouts.
| Code | Status | Message |
guard.actor_ready_timeout | 503 | Timed out waiting for actor to become ready. Ensure that the pool selector is accurate and there are runners available in the namespace you created this actor. |
guard.actor_stopped_while_waiting | 503 | Actor stopped while waiting for a response. |
guard.invalid_request | | Invalid request. |
guard.missing_header | | Missing header required for routing. |
guard.query_invalid_params | | invalid query gateway params |
guard.rate_limit | 429 | Too many requests. Try again later. |
guard.service_unavailable | 503 | Service unavailable. |
inspector
| Code | Status | Message |
inspector.invalid_request | | Invalid inspector request |
inspector.unauthorized | | Inspector request requires a valid bearer token |
message
Message size limits on connections.
| Code | Status | Message |
message.incoming_too_long | 400 | Incoming message too long. |
message.outgoing_too_long | 400 | Outgoing message too long |
namespace
Namespace lookup and creation.
| Code | Status | Message |
namespace.invalid | | Namespace list limit must be between 1 and 100. |
namespace.name_not_unique | 409 | A namespace with this name already exists. |
namespace.not_found | 404 | The namespace does not exist. |
napi
| Code | Status | Message |
napi.invalid_argument | | Invalid native argument |
napi.invalid_state | | Invalid native state |
pool
Node pool configuration.
| Code | Status | Message |
pool.invalid | | Node pool configuration is invalid. |
pool.nodes_connected | 409 | The node pool still has connected nodes. |
pool.not_found | 404 | The node pool does not exist. |
pool.serverless_unsupported | | Serverless node pools are not supported. |
protocol
Encoding and framing of connection protocol messages.
| Code | Status | Message |
protocol.invalid_actor_connect_request | | Invalid actor-connect request. |
protocol.invalid_http_request | | Invalid HTTP request. |
protocol.invalid_http_response | | Invalid HTTP response. |
protocol.invalid_persisted_data | | Invalid persisted actor data. |
protocol.unsupported_encoding | | Unsupported protocol encoding. |
queue
Actor queues.
| Code | Status | Message |
queue.already_completed | 400 | Queue message was already completed |
queue.complete_not_configured | 400 | Queue message does not support completion |
queue.completion_waiter_conflict | 400 | Queue completion waiter conflict |
queue.completion_waiter_dropped | 400 | Queue completion waiter dropped before response |
queue.full | 400 | Queue is full |
queue.invalid_message_key | 400 | Queue message key is invalid |
queue.message_too_large | 400 | Queue message is too large |
queue.timed_out | 400 | Queue wait timed out |
registry
| Code | Status | Message |
registry.shut_down | | Registry is shut down. |
request
| Code | Status | Message |
request.invalid | | Invalid request. |
runner
| Code | Status | Message |
runner.not_found | | The runner does not exist. |
runner_pool
| Code | Status | Message |
runner_pool.invalid | | Invalid runner pool. |
runner_pool.not_found | | No config for this runner exists. |
serverless_runner_pool
| Code | Status | Message |
serverless_runner_pool.not_found | | No serverless pool for this runner exists. |
sqlite
| Code | Status | Message |
sqlite.closed | | SQLite database is closed. |
sqlite.invalid_bind_parameter | | Invalid SQLite bind parameter. |
sqlite.invalid_compile_options | | SQLite requires SQLITE_ENABLE_BATCH_ATOMIC_WRITE and SQLITE_DIRECT_OVERFLOW_READ=0. Rebuild with LIBSQLITE3_FLAGS="SQLITE_ENABLE_BATCH_ATOMIC_WRITE SQLITE_DIRECT_OVERFLOW_READ=0". |
sqlite.not_configured | | SQLite is not configured. |
sqlite.remote_execution_failed | | Remote SQLite execution failed. |
sqlite.remote_fence_mismatch | | Remote SQLite generation is stale. |
sqlite.remote_indeterminate_result | | Remote SQLite result is indeterminate. |
sqlite.remote_unavailable | | Remote SQLite is unavailable. |
sqlite.unavailable | | SQLite is unavailable. |
topology
| Code | Status | Message |
topology.unsupported_version | | The peer does not read any version of this family that this binary writes. |
topology.version_unavailable | | No version of this family is both readable by every storage worker and writable here. |
topology.version_unknown | | The storage workers that read persisted data are unknown. |
ups
| Code | Status | Message |
ups.consumer_closed | | The consumer closed without replying; the operation may have executed. |
ups.dispatch_rejected | | The caller revoked the request before dispatch. |
ups.endpoint_unresolved | | The worker's endpoint could not be resolved; the request was not sent. |
ups.invalid_message | | The message exceeds the limit or has an invalid subject. |
ups.invalid_stream | | The packet stream is malformed or ended without a terminal frame. |
ups.no_responders | | The worker has no consumer for this subject. |
ups.overloaded | | UPS capacity is full; the operation was not admitted. |
ups.subscription_exists | | This worker already has a consumer for the subject. |
ups.timeout | | The operation deadline expired; it may still have completed. |
ups.transport | | Worker transport failed; the operation may have executed. |
ups.unexpected_packet | | Expected exactly one packet followed by the end of the stream. |
ups.unknown_worker | | The worker is not in current membership. |
ups.wrong_worker | | The target worker incarnation has changed. |
user
Errors thrown by your actor code. The code is whatever you pass to UserError.
validation
Request validation.
| Code | Status | Message |
validation.invalid_input | | Invalid input. |
wasm
| Code | Status | Message |
wasm.invalid_config | | Invalid wasm configuration. |
wasm.invalid_state | | Invalid wasm state |
ws
WebSocket handling for the connection protocol and onWebSocket handlers.
| Code | Status | Message |
ws.connection_closed | | Normal connection close. |
ws.eviction | | The websocket has been evicted and should not attempt to reconnect. |
ws.invalid_request | | The websocket could not open due to an invalid request. |
ws.timed_out | | Ping timed out. |