---
title: Errors
description: The error responses the Hexel Studio API and token service return,
  and what each one means.
url: https://hexelstudio.com/docs/identity/errors
---

Errors come from two places, with two JSON shapes:

- **The gateway** at `api.hexelstudio.com` answers before your request reaches a service: missing or invalid credentials, rate limits, unknown paths, timeouts. Its body is an `error` object.
- **The service** that handles the request answers everything else: permissions, validation, plan limits, conflicts. Its body has an `error` string, sometimes with more fields.

The token service at `sts.hexelstudio.com` uses a third, OAuth-style shape. See [Token service errors](#token-service-errors).

Most responses, including errors, carry an `X-Request-Id` header. Include it when you contact support.

## Gateway errors

```json
{
  "error": {
    "code": "401",
    "message": "Authentication is required or the provided credentials are invalid."
  }
}
```

`code` is the HTTP status as a string. `message` is meant for people; don't match on it.

| Status | `message` | Cause |
| --- | --- | --- |
| 401 | `Authentication is required or the provided credentials are invalid.` | No `Authorization` header or API key, or the access token is expired, malformed or not issued by Hexel Studio. |
| 401 | `Invalid API key.` | The `X-API-Key` value is not a valid, active API key. |
| 403 | `X-Organization-Id does not match the API key's organization.` | You sent an API key and an `X-Organization-Id` for a different organization. |
| 403 | `Internal endpoint is not publicly accessible.` | The path is not part of the public API. |
| 404 | `Resource not found` | No public API matches the path. |
| 408 | `The server timed out waiting for the request.` | The request body arrived too slowly. |
| 413 | `The request body exceeds the maximum allowed size.` | The body is too large. |
| 429 | `Rate limit exceeded. Try again later.` | You hit a rate limit. See [Rate limits](#rate-limits). |
| 429 | `Too many invalid API key attempts. Try again later.` | Too many requests with invalid API keys came from your IP address. |
| 500 | `An unexpected error occurred on the server.` | A gateway error. Retry later. |
| 502 | `The gateway received an invalid response from the upstream service.` | The service failed. Retry later. |
| 503 | `API key authentication is temporarily unavailable.` | The API key could not be checked. Retry later. |
| 503 | `The service is temporarily unavailable.` | The service is down or restarting. Retry later. |
| 504 | `The upstream service did not respond in time.` | The service was too slow. Retry later. |

A 502 or 504 can also arrive as an HTML page from Hexel Studio's network edge instead of this JSON.

### Rate limits

Identity and access endpoints are rate limited per minute, per caller and per organization. A request over a limit gets `429` with the gateway body above and these headers:

| Header | Meaning |
| --- | --- |
| `Retry-After` | Seconds until the current one-minute window ends. Wait at least this long. |
| `X-RateLimit-Limit` | The limit you exceeded, in requests per minute. |
| `X-RateLimit-Scope` | Which limit: `principal_reads`, `principal_writes`, `principal_sensitive_writes`, `org_reads` or `org_writes`. |

For the values and what each scope counts, see [Limits](https://hexelstudio.com/docs/identity/limits).

## Service errors

Most service errors have a single `error` field. It is either a short code, such as `forbidden`, or a sentence:

```json
{ "error": "forbidden" }
```

```json
{ "error": "workspace not found" }
```

If you send `X-Organization-Id` with an access token for a different organization, the service can't identify you and answers `401 unauthorized` or `403 forbidden`.

Match on the HTTP status and on the named codes below. Treat other `error` text as a message for people; it can change.

### Named error codes

| Status | `error` | Meaning |
| --- | --- | --- |
| 401 | `unauthorized` | The service could not identify the caller. |
| 403 | `forbidden` | The caller is not allowed to do this. See [Permission errors](#permission-errors). |
| 403 | `quota_exceeded` | A plan limit was reached. See [Plan limit errors](#plan-limit-errors). |
| 409 | `last_owner` | The change would leave the organization without an owner. See [Members](https://hexelstudio.com/docs/identity/members#rank-rules). |
| 422 | `not_org_member` | You tried to add someone to a workspace who is not a member of its organization. See [Workspaces](https://hexelstudio.com/docs/identity/workspaces#workspace-members). |

`last_owner` and `not_org_member` also have a `message`:

```json
{
  "error": "last_owner",
  "message": "the organization must keep at least one owner"
}
```

### Permission errors

A `403 forbidden` means the caller's policies don't allow the action in this organization, workspace or environment. Some responses name what is missing.

When an endpoint needs one specific permission, the body can include it as `required`:

```json
{ "error": "forbidden", "required": "iam:role:write_trust" }
```

When you try to grant access you don't hold yourself, for example by attaching a policy, the body lists the actions you are missing:

```json
{
  "error": "forbidden",
  "reason": "cannot grant actions the caller does not hold",
  "missing_actions": ["iam:policy:write"]
}
```

A member-rank refusal is also `403`, with a sentence in `error`, such as `"cannot assign role equal or higher than your own"`. See [Members](https://hexelstudio.com/docs/identity/members#rank-rules).

To find out why a request was denied, see [Test access](https://hexelstudio.com/docs/identity/test-access).

### Plan limit errors

```json
{
  "error": "quota_exceeded",
  "quota_key": "workspaces_per_org",
  "limit": 3,
  "current": 3,
  "message": "plan limit reached: this organization can have at most 3 workspaces; upgrade the plan or contact Hexel"
}
```

| Field | Meaning |
| --- | --- |
| `quota_key` | The limit: `workspaces_per_org`, `environments_per_workspace`, `members_per_org` or `invitations_per_day`. |
| `limit` | Your organization's limit. |
| `current` | How many you have now. |
| `message` | A sentence for people. |

See [Limits](https://hexelstudio.com/docs/identity/limits).

### Other status codes

| Status | When |
| --- | --- |
| 400 | The body is not valid JSON, a required field is missing, or a value is not allowed, such as an unknown member role. `error` describes the problem. |
| 404 | The resource doesn't exist. A resource of another organization also answers `404`, so you can't tell the two apart. |
| 409 | The request conflicts with existing data, for example a duplicate name. |
| 503 | `POST /v1/organizations` returns `503` while the new organization is still being set up. Send the same request again; see below. |

The organization-setup response looks like this:

```json
{
  "error": "organization provisioning is pending; retry the same request",
  "org_id": "<org-id>",
  "provisioning_status": "PENDING"
}
```

## Token service errors

The token service (`https://sts.hexelstudio.com/token` and its other endpoints) answers with an `error` field and, for some errors, an `error_description`:

```json
{
  "error": "invalid_grant",
  "error_description": "subject_token was revoked"
}
```

| Status | `error` | Meaning |
| --- | --- | --- |
| 400 | `invalid_request` | A required parameter is missing, such as `subject_token` or `resource`. |
| 400 | `invalid_target` | The `resource` (the role to assume) is not valid. |
| 400 | `unsupported_token_type` | The `subject_token_type` is not supported. |
| 400 | `unsupported grant_type` | The `grant_type` is not one the token service accepts. The response lists the supported ones in `supported`. |
| 401 | `invalid_grant` | The subject token is not a valid Hexel Studio access token, or it was revoked. |
| 403 | `access_denied` | You may not assume the role, for example because its trust policy does not allow you. See [Roles](https://hexelstudio.com/docs/identity/roles). |
| 403 | `organization context denied` | You are not an active member of the organization you asked for, or it is not active. |
| 429 | `rate_limited` | Too many tokens were issued for this credential in the last minute. |
| 503 | `temporarily_unavailable` | Try again later. |

Other token service errors have a sentence in `error`, such as `"invalid api key"`, `"invalid client credentials"`, `"refresh token expired"` or `"token revoked"`. See [Authenticate to the API](https://hexelstudio.com/docs/identity/authenticate) and [Tokens](https://hexelstudio.com/docs/identity/tokens).
