Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Error Codes

All error responses use the ErrorResponse protobuf message with a human-readable message field and a machine-readable error_code field. Clients MUST use error_code for programmatic decisions (e.g., auto-logout), not the message text. See API Conventions — Error Codes for the full ErrorCode enum definition and range conventions.

Status Code Reference

400 Bad Request

Returned when the request contains invalid input.

ConditionError CodeExample message
Invalid username formatERROR_CODE_INPUT_VALIDATION"username must start with a letter or digit..."
Password too shortERROR_CODE_INPUT_VALIDATION"password must be at least 8 characters"
Alias too longERROR_CODE_INPUT_VALIDATION"alias exceeds maximum length"
Alias contains control charactersERROR_CODE_INPUT_VALIDATION"must not contain ASCII control characters"
Invalid group name formatERROR_CODE_INPUT_VALIDATIONSame as username validation
Missing required fieldERROR_CODE_INPUT_BAD_REQUEST"invitee_id is required"
Empty required fieldERROR_CODE_INPUT_BAD_REQUEST"commit_message is required"
Invalid message expiry valueERROR_CODE_INPUT_BAD_REQUEST"message_expiry_seconds must be -1, 0, or positive"
Group expiry exceeds server retentionERROR_CODE_INPUT_BAD_REQUEST"group expiry cannot exceed server retention policy"
Key package too largeERROR_CODE_INPUT_BAD_REQUEST"key package exceeds maximum size"
Key package wire format invalidERROR_CODE_INPUT_BAD_REQUEST"invalid key package wire format"
Target not a group memberERROR_CODE_INPUT_BAD_REQUEST"user is not a member of this group"
Target not an adminERROR_CODE_INPUT_BAD_REQUEST"user is not an admin"
Cannot demote last adminERROR_CODE_INPUT_BAD_REQUEST"cannot demote the last admin"
No GroupInfo available for external joinERROR_CODE_INPUT_BAD_REQUEST"no group info available"

401 Unauthorized

Returned when authentication or authorization fails.

ConditionError CodeContext
Missing auth headerERROR_CODE_AUTH_HEADER_MISSINGAny authenticated endpoint
Invalid auth header formatERROR_CODE_AUTH_HEADER_INVALIDMissing Bearer prefix on standard header
Invalid or expired tokenERROR_CODE_AUTH_TOKEN_EXPIREDAny authenticated endpoint
Invalid username or passwordERROR_CODE_AUTH_TOKEN_EXPIREDPOST /api/v1/login
Not a member of the groupERROR_CODE_GROUP_NOT_MEMBERGroup-scoped endpoints requiring membership
Not an admin of the groupERROR_CODE_GROUP_NOT_ADMINAdmin-only endpoints
Not the invitee for this inviteERROR_CODE_GROUP_NOT_MEMBERPOST /api/v1/invites/{id}/accept or decline

Clients SHOULD auto-logout only on ERROR_CODE_AUTH_TOKEN_EXPIRED (code 202). Auth header errors (200, 201) indicate a configuration mismatch that won’t be resolved by re-logging in. Group membership/admin errors (400, 401) are operational and should be displayed as regular error messages.

403 Forbidden

Returned when access is explicitly denied by server policy.

ScenarioError CodeEndpoint(s)
Group is not publicERROR_CODE_GROUP_NOT_PUBLICPOST /api/v1/groups/{id}/join when group visibility is PRIVATE
User is bannedERROR_CODE_GROUP_BANNEDPOST /api/v1/groups/{id}/join, POST /api/v1/groups/{id}/escrow-invite, POST /api/v1/invites/{id}/accept
ConditionError CodeContext
Registration disabledERROR_CODE_RESOURCE_FORBIDDENPOST /api/v1/register when registration_enabled is false and no valid token provided
Invalid registration tokenERROR_CODE_RESOURCE_FORBIDDENPOST /api/v1/register with incorrect registration_token

404 Not Found

Returned when the referenced resource does not exist.

ConditionError CodeContext
User not foundERROR_CODE_RESOURCE_NOT_FOUNDGET /api/v1/users/{username}, GET /api/v1/users/by-id/{user_id}
No key packages availableERROR_CODE_RESOURCE_NOT_FOUNDGET /api/v1/key-packages/{user_id}
No GroupInfo storedERROR_CODE_RESOURCE_NOT_FOUNDGET /api/v1/groups/{id}/group-info
Invite not foundERROR_CODE_RESOURCE_NOT_FOUNDPOST /api/v1/invites/{id}/accept, decline
Welcome not foundERROR_CODE_RESOURCE_NOT_FOUNDPOST /api/v1/welcomes/{id}/accept
No pending invite for group+inviteeERROR_CODE_RESOURCE_NOT_FOUNDPOST /api/v1/groups/{id}/cancel-invite
Target user does not existERROR_CODE_RESOURCE_NOT_FOUNDPOST /api/v1/groups/{id}/invite, remove, promote, demote

Non-existent groups return 401 (not 404) on group-scoped endpoints to prevent group existence probing.

409 Conflict

Returned when the request conflicts with existing state.

ConditionError CodeContext
Username already takenERROR_CODE_RESOURCE_CONFLICTPOST /api/v1/register
Group name already takenERROR_CODE_RESOURCE_CONFLICTPOST /api/v1/groups
User already a group memberERROR_CODE_RESOURCE_CONFLICTPOST /api/v1/groups/{id}/invite, escrow-invite
User already an adminERROR_CODE_RESOURCE_CONFLICTPOST /api/v1/groups/{id}/promote
Duplicate pending inviteERROR_CODE_RESOURCE_CONFLICTPOST /api/v1/groups/{id}/escrow-invite

429 Too Many Requests

Returned when a rate limit is exceeded.

ConditionError CodeContext
Key package fetch rate exceededERROR_CODE_UNSPECIFIEDGET /api/v1/key-packages/{user_id} (10 req/min per target user)

500 Internal Server Error

Returned for unexpected server-side failures.

ConditionError CodeNotes
Database errorsERROR_CODE_UNSPECIFIEDConnection failures, query errors, constraint violations
Password hashing failuresERROR_CODE_UNSPECIFIEDArgon2id computation errors
Protobuf encoding failuresERROR_CODE_UNSPECIFIEDSerialization errors

The server MUST NOT expose internal details in the error message. The message field SHOULD be a generic string such as "internal server error".

Error Response Format

All errors use the ErrorResponse protobuf message:

message ErrorResponse {
  string message = 1;     // Human-readable error description
  ErrorCode error_code = 2; // Machine-readable error code
}

Clients SHOULD display the message field to the user or include it in logs. Clients MUST use the error_code field for programmatic control flow (e.g., distinguishing token expiry from auth header misconfiguration).

Notes

  • The server uses HTTP 401 for both authentication failures (invalid token) and authorization failures (not a group member, not an admin). The error_code field distinguishes these: ERROR_CODE_AUTH_* codes indicate authentication issues, while ERROR_CODE_GROUP_* codes indicate authorization issues.
  • Error messages are informational and intended for human consumption. Clients MUST use error_code for programmatic decisions, not the message text.