Skip to content

Errors

This page helps you handle the errors the Admin API and the Account API answer.

Every error comes back as a JSON body with the same two fields:

{
"error_code": "VALIDATION_ERROR",
"error_description": "SMTP host is required."
}

Decide what to do from the HTTP status first: a 4xx is something your request can fix, and a 5xx is a problem on the server. Then read error_code for the specific case, and show or log error_description.

  • error_code is a stable identifier for the failure. It’s either an UPPER_SNAKE code from the table below, or, for a refused field the auth server can describe in several languages, a catalog key in dotted lowercase, such as validator.email.invalid_format.
  • error_description is a sentence for people. For a catalog key it’s in the request’s language; otherwise it’s in English. Don’t match on it: the wording can change, the code won’t.

The protocol endpoints, /auth/authorize, /auth/token, /connect/register and /userinfo, answer errors in the format their standards define, not this one. Authorize, Token and UserInfo cover theirs, and Dynamic client registration the registration endpoint’s.

This is every UPPER_SNAKE code the two APIs answer.

Code Status Meaning
VALIDATION_ERROR 400 A value was refused. error_description says which and why.
INVALID_REQUEST_BODY 400 The body isn’t the JSON the operation expects.
INVALID_REQUEST 400 The Authorization header or the access_token parameter was sent twice, the token was sent two ways at once, or a form body doesn’t parse.
EMAIL_TOO_LONG 400 The new user’s email address is longer than 60 characters.
VALUE_TOO_LONG 400 A user attribute’s value is longer than 250 characters.
FILE_TOO_LARGE 400 The uploaded picture or logo is over the size limit, or the form doesn’t parse.
NO_FILE 400 The upload has no picture field.
AUTHENTICATION_FAILED 400 The password sent to confirm a password change, an email change, or turning two-factor authentication on or off is wrong. For two-factor authentication, a missing password answers it too.
OTP_CODE_REQUIRED 400 Two-factor authentication was turned on without a code.
INVALID_OTP_CODE 400 The code isn’t six digits, or it doesn’t match the authenticator.
OTP_ENROLLMENT_NOT_PENDING 400 No enrollment is pending, or it expired. Start a new one with GET /api/v1/account/otp/enrollment.
SECRET_KEY_NOT_ACCEPTED 400 The request sent a secretKey. Start an enrollment and send only the code from the authenticator.
OTP_ALREADY_ENABLED 400 Two-factor authentication is already on.
OTP_NOT_ENABLED 400 Two-factor authentication is already off.
INVALID_OR_EXPIRED_VERIFICATION_CODE 400 The email verification code is wrong or has expired.
SMTP_NOT_ENABLED 400 The operation needs to send email, and SMTP is off: a test email, or sending or checking an email verification code.
SEND_FAILED 400 The test email couldn’t be sent. error_description says what to check.
ACCESS_TOKEN_REQUIRED 401 No access token was sent.
INVALID_TOKEN 401 The token is malformed, expired, not an access token for authserver, or its user or session is gone.
INVALID_SESSION 401 On POST /api/v1/account/logout-request: the token carries no session id (sid), its session is gone, or the token’s client isn’t part of that session.
INSUFFICIENT_SCOPE 403 The token carries none of the scopes the operation accepts. The WWW-Authenticate header says error="insufficient_scope".
USER_CONTEXT_REQUIRED 403 An Account API call was made with a token that wasn’t issued for a user, such as one from the client credentials flow, carrying authserver:manage-account. Without it, the answer is INSUFFICIENT_SCOPE.
FORBIDDEN 403 The token is valid, but the consent or session it names belongs to another user.
MANAGE_SCOPE_REQUIRED 403 The request acts on an administrator or an administrative permission, which only authserver:manage may do. See Administrators.
NOT_FOUND 404 Nothing has that id.
CONCURRENT_UPDATE 409 Another request changed what yours was based on. Nothing was saved: read it again and retry.
EMAIL_ALREADY_EXISTS 409 Another user already has that email address.
LAST_ADMINISTRATOR 409 The change would leave no enabled user holding authserver:manage. Grant it to another user first.
ROTATION_IN_PROGRESS 409 Another signing key rotation won the race, and this call rotated nothing. Don’t retry: the rotation it ran into already happened.
TOO_MANY_REQUESTS 429 A rate limit was reached. The Retry-After header says how many seconds to wait.
INTERNAL_SERVER_ERROR 500 The request failed inside the server. error_description ends with a request id an operator can find in the server’s log. Retrying is reasonable.
KEY_SET_INCOMPLETE 500 A signing key rotation found no current or no next key. That’s a deployment problem a retry won’t clear. error_description ends with a request id, as for INTERNAL_SERVER_ERROR.

An operation that replaces a whole list, such as a client’s redirect URIs or a user’s groups, also takes the list as you last read it, in a field named expected and the list’s name, such as expectedRedirectURIs. When the stored list is no longer that one, because someone else saved it in between, the save is answered 409 with CONCURRENT_UPDATE and changes nothing. Read the list again, apply your change to it, and save again.