Error codes
When the sync server refuses a request it answers with an HTTP error status and a JSON body:
{ "code": "TOTP_REQUIRED", "message": "Two-factor code required", "details": {} }code is one of the values below and stays the same between versions; message is English text for people and may change; details is there for some codes and says more (which vaults, which rule). The apps turn each code into a message of their own in your language.
| Code | HTTP status | Meaning |
|---|---|---|
ACCOUNT_DELETED |
401, 403 | The account is scheduled for deletion. It can be restored during its restore window. |
AI_NOT_CONFIGURED |
404 | The server has no AI service set up (STERNWAY_AI_PROXY), so it cannot pass AI requests on. |
AI_UPSTREAM_FAILED |
502 | The AI service the server passes requests to answered with an error. |
AI_UPSTREAM_TIMEOUT |
504 | The AI service did not answer in time (120 seconds unless the server sets another limit). |
APP_TOO_OLD |
426 | The team requires a newer Sternway than the one asking (the team’s oldest-version policy). Update the app. |
CONFLICT |
409 | The request clashes with something the server already holds: an email, handle or SSO organization name another account or team uses, an id that exists, a proposal already resolved (message says which). |
CURSOR_EXPIRED |
410 | The sync position the app sent is older than what the server still keeps for a vault. The app does a full resync of those vaults. |
DEVICE_REVOKED |
401 | This device was removed from the account. It is signed out; its own data stays on it. |
EMAIL_CODE_INVALID |
400 | The emailed verification code is wrong or has expired. |
FORBIDDEN |
403 | The account may not do this (for example a member who can only view a vault tried to change it). |
INTERNAL |
500 | Something failed on the server. The server log says what; the request can be tried again. |
INVALID_CREDENTIALS |
401 | The email or the password-derived key is wrong. |
ITEM_TOO_LARGE |
413 | An item is larger than 256 KiB, or the request body is too large. |
MAIL_FAILED |
502 | The server could not send the email. |
MAIL_NOT_CONFIGURED |
400 | The server cannot send email (STERNWAY_SMTP_URL is not set). |
NOT_FOUND |
404 | There is no such account, vault, team or item, or the account cannot see it. |
NOT_IMPLEMENTED |
501 | The route exists in the contract but this server does not offer it. |
OWNER_MUST_TRANSFER |
400 | The team owner can’t leave without choosing a new owner first, or deleting the team. |
PASSKEY_INVALID |
401 | The passkey sign-in or registration could not be verified. |
PASSKEY_LIMIT |
409 | The account already has the most passkeys it may have. |
PASSWORD_CHANGED |
401 | The account’s password was changed on another device, which signs every other session out. Sign in again with the new password. |
PLAN_REQUIRED |
403 | The team’s plan or the server’s licence does not include this feature. |
PORTAL_NOT_CONFIGURED |
404 | This server has no licence portal. |
RATE_LIMITED |
429 | Too many requests or sign-in attempts in a short time. Wait and try again. |
REAUTH_EXPIRED |
401 | The password confirmation for adding a passkey is too old. Start again. |
SESSION_SCOPE |
401, 403 | A licence-only session was used for something other than the licence routes. |
SSO_INVALID |
401 | The single sign-on ticket is unknown, used or expired, or belongs to another account. |
SSO_NOT_CONFIGURED |
404 | Single sign-on is not set up on this server, or no team uses that SSO organization name. |
SSO_PROVIDER_ERROR |
502 | The identity provider could not be reached or gave an answer the server could not use. |
SSO_REQUIRED |
403 | The server or the team requires single sign-on: sign in with SSO instead. |
STALE_KEY_VERSION |
409 | The vault’s key was rotated since the app encrypted the item. The app takes the new key and sends it again. |
STEP_UP_REQUIRED |
403 | Confirm it is you first (password and, with two-factor on, a code) before this change. |
TEAM_2FA_REQUIRED |
403 | The team requires two-factor authentication: turn it on for your account to use the team’s vaults. |
TEAM_ATTESTATION_DEVICES |
409 | A member already reports from the most devices the server takes for one team. |
TEAM_ATTESTATION_INVALID |
400 | A device report that is not signed by the member it names, for this team. |
TEAM_CHANGE_NOT_ALLOWED |
403 | The team’s rules do not allow this signer to make this change (details.rule names the rule). |
TEAM_CHECKPOINT_NEEDED |
409 | The team has collected the most admin-signed changes it may before the owner’s app checkpoints them. Only safety changes go through until then. |
TEAM_CLOCK_SKEW |
400 | A signed team change is dated more than 5 minutes from the server’s clock. Check the device’s clock. |
TEAM_DELEGATION_OFF |
403 | The server’s administrator turned off changes signed by admins (STERNWAY_DELEGATED_SIGNING=off). The owner’s changes still work. |
TEAM_ENVELOPE_EXISTS |
409 | A vault key for this member is already there and only the owner may replace it. |
TEAM_FEATURE_NOT_ENTITLED |
403 | The change uses a feature the team’s plan or licence does not include (details.features). |
TEAM_GRANT_TOO_LONG |
400 | Access with an end further away than the team’s longest-access policy allows. (Listed in the API contract; this server version does not send it.) |
TEAM_GROWTH_RESERVE |
409 | An admin’s change would grow the team’s signed list past 90% of its size limit; the rest is kept for the owner. |
TEAM_HISTORY_PRUNED |
410 | The server no longer keeps that part of the team history. The app keeps what it verified. |
TEAM_NAME_MISMATCH |
400 | The name typed to confirm deleting a team is not the team’s name. |
TEAM_OWNER_ENVELOPE_REQUIRED |
400 | A new or rotated team vault key must include the copy sealed for the owner. |
TEAM_OWNER_PRIORITY |
409 | The owner is changing the team; try again in a minute. |
TEAM_PASSKEY_REQUIRED |
403 | The team requires signing in with a passkey to use its vaults. |
TEAM_POLICY_HOSTS |
403 | The team lets only its owner and admins add hosts to its vaults. |
TEAM_POLICY_SIGNED |
409 | This setting is part of the team’s signed policy and is changed there, not directly. |
TEAM_PROPOSAL_INVALID |
400 | A proposal that does not decode or is not signed by the member who sent it. |
TEAM_PROPOSAL_REPLAY |
409 | This proposal was sent before. |
TEAM_PROPOSAL_REQUIRED |
409 | Past today’s limit for this signer, or the owner asked to approve such changes: the app sends it to the owner as a proposal. |
TEAM_RELAX_TOO_EARLY |
400 | A relaxed policy is set to take effect before the delay the owner chose. |
TEAM_ROTATION_LIMIT |
429 | The vault’s key was rotated by admins 3 times today already. |
TEAM_SEATS_EXCEEDED |
403 | The server has more accounts in teams than its licence allows, for more than 30 days: new invites stop until seats are added or members removed. |
TEAM_SERVER_UPDATE_NEEDED |
409 | The change uses a version of the team rules this server does not know. Update the server. |
TEAM_SIGNER_TAIL_SHARE |
409 | This admin signed their share of the team’s recent changes; the owner signs next. |
TEAM_STATEMENT_EPOCH |
409 | Another device changed the team first. The app reads the team’s list again and signs once more. |
TEAM_STATEMENT_INVALID |
400 | A signed team change that does not decode, is not signed by its signer, or does not follow the list the server holds. |
TEAM_UPGRADE_TOMBSTONES |
409 | Upgrading the team must carry the ids of the vaults the team deleted before. |
TEAM_VAULT_DELETED |
410 | The team vault was deleted. Its owner can restore it until it is purged. (Listed in the API contract; this server version does not send it.) |
TEAM_VAULT_ID_USED |
409 | The team used this vault id before; a new vault needs a new id. |
TOTP_INVALID |
401 | The two-factor code (or the recovery code) is wrong. |
TOTP_REQUIRED |
401 | The account has two-factor authentication on: send the authenticator code too. |
UNAUTHENTICATED |
401 | No session token, an expired one, or an unknown, used or expired ticket. Sign in again. |
VALIDATION |
400 | The request does not match the route’s schema (details says which field). |
The sternway-cli command has its own codes and exit statuses: see sternway-cli.
© 2026 IRONPINE LABS LLC
ALL RIGHTS RESERVED.