# Errors Every error from the InfraNest API has the same shape and a stable `code`. Write your scripts against the code: the message is for people and may be reworded, the code never changes. ```json { "code": "scope_missing", "message": "This API token does not have the dns.write scope.", "hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.", "retryable": false, "docs_url": "https://developers.infranest.io/errors#scope_missing", "reference": "k3j9x0b2qa", "required": "dns.write" } ``` | Field | Meaning | |---|---| | `code` | What kind of error this is. Stable: new codes are added, existing ones never change. | | `message` | A sentence for people. May be reworded. | | `hint` | What to do about it. | | `retryable` | Whether sending the same request again later can work without changing anything. | | `docs_url` | This page, at the code's entry. | | `reference` | The request's ID. Quote it when you contact support. Also in the `X-Request-Id` header. | | `retry_after` | Seconds to wait, when the error says to wait. Also in the `Retry-After` header. | | `required` | The token scope that was missing (`scope_missing`). | | `required_permission` | The role permission that was missing (`permission_denied`). | | `limit_key`, `limit`, `usage` | Which plan limit was hit, and how much of it is used (`plan_limit`). | | `errors` | Each invalid field and what is wrong with it (`validation_failed`). | | `max_range_seconds`, `resolution`, `resolutions` | The longest range the asked resolution takes, and the resolutions that would fit the range you sent (`range_too_large`). | Some endpoints answer a code of their own, specific to what they do. Those are listed on the endpoint's reference page. For problems that are not one error code — a token that stopped working, an assistant that cannot connect — see [Troubleshooting](troubleshooting.md). ## Codes | Code | Status | Retry? | |---|---|---| | [`unauthenticated`](#unauthenticated) | 401 | No | | [`scope_missing`](#scope_missing) | 403 | No | | [`session_only`](#session_only) | 403 | No | | [`not_token_writable`](#not_token_writable) | 403 | No | | [`write_disabled`](#write_disabled) | 403 | No | | [`wrong_organization`](#wrong_organization) | 403 | No | | [`token_ip_not_allowed`](#token_ip_not_allowed) | 403 | No | | [`test_token_required`](#test_token_required) | 403 | No | | [`test_token_sandbox_only`](#test_token_sandbox_only) | 403 | No | | [`api_token_required`](#api_token_required) | 403 | No | | [`sandbox_personal`](#sandbox_personal) | 409 | No | | [`sandbox_needs_organization`](#sandbox_needs_organization) | 409 | No | | [`organization_offline`](#organization_offline) | 409 | No | | [`permission_denied`](#permission_denied) | 403 | No | | [`forbidden`](#forbidden) | 403 | No | | [`organization_suspended`](#organization_suspended) | 403 | No | | [`read_only_session`](#read_only_session) | 403 | No | | [`sso_required`](#sso_required) | 403 | No | | [`two_factor_setup_required`](#two_factor_setup_required) | 403 | No | | [`password_reset_required`](#password_reset_required) | 403 | No | | [`email_verification_required`](#email_verification_required) | 403 | No | | [`plan_limit`](#plan_limit) | 402 | No | | [`not_found`](#not_found) | 404 | No | | [`method_not_allowed`](#method_not_allowed) | 405 | No | | [`conflict`](#conflict) | 409 | No | | [`validation_failed`](#validation_failed) | 422 | No | | [`unprocessable`](#unprocessable) | 422 | No | | [`range_too_large`](#range_too_large) | 422 | No | | [`rate_limited`](#rate_limited) | 429 | Yes | | [`idempotency_key_reused`](#idempotency_key_reused) | 422 | No | | [`idempotency_in_progress`](#idempotency_in_progress) | 409 | Yes | | [`provider_refused`](#provider_refused) | 4xx / 502 | No | | [`provider_rate_limited`](#provider_rate_limited) | 429 | Yes | | [`provider_unavailable`](#provider_unavailable) | 502 | Yes | | [`maintenance`](#maintenance) | 503 | Yes | | [`server_error`](#server_error) | 500 | Yes | ### unauthenticated {#unauthenticated} You are not signed in, or the API token is missing, wrong, expired or revoked. **Why it happens:** No Authorization header was sent, the token was mistyped or cut off, or it has expired or been revoked. New tokens expire after 90 days unless another period was chosen. **What to do:** Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked. **Retry the same request:** No ### scope_missing {#scope_missing} This API token does not have the scope this request needs. **Why it happens:** The token was created without the scope for this area, or with only the read scope where the request changes something. **What to do:** Create a token that includes the scope named in "required". Give each token only the scopes it needs. **Retry the same request:** No ### session_only {#session_only} This can only be done in the InfraNest app while signed in, not with an API token. **Why it happens:** The address belongs to the part of InfraNest a token may never use: account and security settings, and API tokens themselves. **What to do:** Do this in the app while signed in. Account and security settings can never be changed with a token. **Retry the same request:** No ### not_token_writable {#not_token_writable} This action is only available in the InfraNest app, not with an API token. **Why it happens:** The request changes something that only the app can change, such as provider actions that cost money or settings with no API. **What to do:** Do this in the app while signed in. The developer docs list everything a token can change. **Retry the same request:** No ### write_disabled {#write_disabled} API write access is not switched on for this organization. **Why it happens:** The token may write, but writes through the API are switched on per organization, and they are not on for this one. **What to do:** Ask an owner of the organization to switch on API write access. Reads keep working meanwhile. **Retry the same request:** No ### wrong_organization {#wrong_organization} This API token is bound to another organization. **Why it happens:** The token was created for one organization, and the address names another. **What to do:** Use a token created for this organization, or one created for all your organizations. **Retry the same request:** No ### token_ip_not_allowed {#token_ip_not_allowed} This API token cannot be used from this address. **Why it happens:** The token is limited to a list of addresses, and this request came from another one: often a CI runner, a VPN, or IPv6 where only an IPv4 address was listed. **What to do:** Call from one of the addresses the token is limited to, or change its address list under My account → Developer. **Retry the same request:** No ### test_token_required {#test_token_required} This is a sandbox organization, and only its own test tokens work here. **Why it happens:** A live token (in_live_…) was sent to a sandbox organization. **What to do:** Create a token while working in the sandbox organization; it starts with in_test_. Live tokens never work in a sandbox. **Retry the same request:** No ### test_token_sandbox_only {#test_token_sandbox_only} This is a test token, and it works only in its sandbox organization. **Why it happens:** A test token (in_test_…) was sent to a live organization. **What to do:** Use a live token for live organizations. Test tokens (in_test_…) are for the sandbox only. **Retry the same request:** No ### api_token_required {#api_token_required} The MCP server takes an API token, not a signed-in session. **Why it happens:** The MCP server was called with a signed-in session rather than an API token or an assistant's OAuth connection. **What to do:** Create an API token in My account → Developer and send it in the Authorization header, after the word Bearer. **Retry the same request:** No ### sandbox_personal {#sandbox_personal} A sandbox is personal: nobody can be invited into it, and it cannot be subscribed or handed to someone else. **Why it happens:** The request tried to invite someone into a sandbox, subscribe it to a plan or hand it to another account. **What to do:** Do this in one of your live organizations instead. **Retry the same request:** No ### sandbox_needs_organization {#sandbox_needs_organization} A sandbox belongs with an organization of your own. **Why it happens:** The account tried to create a sandbox before belonging to any organization. **What to do:** Create or join an organization first, then make your sandbox. **Retry the same request:** No ### organization_offline {#organization_offline} This organization does not reach the internet, so nothing was looked up or sent. **Why it happens:** The request needed something from outside — a provider, a DNS lookup, a message — and this organization is a sandbox, a demo or suspended, which never call out. **What to do:** A sandbox, a demo or a suspended organization never calls out. Try it in a live organization. **Retry the same request:** No ### permission_denied {#permission_denied} Your role in this organization does not allow this. **Why it happens:** A token acts as the person who created it, so their role in the organization applies, and that role does not include this. **What to do:** Ask an owner to give your role the permission named in "required_permission". **Retry the same request:** No ### forbidden {#forbidden} You are not allowed to do this. **Why it happens:** A refusal without a more specific reason, most often the wrong organization or the wrong account. **What to do:** Check that you are using the right organization and account. **Retry the same request:** No ### organization_suspended {#organization_suspended} This organization is suspended, so nothing in it can be changed. **Why it happens:** The organization has been suspended. Changes are refused; reading still works. **What to do:** Contact InfraNest support to restore the organization. Reading data still works. **Retry the same request:** No ### read_only_session {#read_only_session} This session is read-only. **Why it happens:** The session is a read-only support view of the account. **What to do:** Someone is viewing this account in read-only support mode; changes must be made by the account holder. **Retry the same request:** No ### sso_required {#sso_required} This organization requires you to sign in with its single sign-on. **Why it happens:** The organization requires single sign-on, and this session signed in another way. **What to do:** Sign in with one of the methods listed in "connections", then try again. **Retry the same request:** No ### two_factor_setup_required {#two_factor_setup_required} This organization requires two-factor authentication on your account. **Why it happens:** The organization requires two-factor authentication, and the account has not set it up yet. **What to do:** Set up two-factor authentication in the app under My account → Security. **Retry the same request:** No ### password_reset_required {#password_reset_required} Your password has expired and must be changed. **Why it happens:** The account's password has to be changed before anything else can be done. **What to do:** Change your password in the app, then try again. **Retry the same request:** No ### email_verification_required {#email_verification_required} Your email address has not been confirmed yet. **Why it happens:** The account's email address has not been confirmed. **What to do:** Open the confirmation link we emailed you, or ask for a new one in the app. **Retry the same request:** No ### plan_limit {#plan_limit} Your plan does not include this, or its limit has been reached. **Why it happens:** The organization's plan does not include this feature, or a counted allowance (API tokens, monitors, domains…) is used up. **What to do:** Upgrade the plan, or free up the limit named in "limit_key" ("usage" of "limit" is used). **Retry the same request:** No ### not_found {#not_found} Nothing exists at this address, or you cannot see it. **Why it happens:** A wrong ID in the address, something that was deleted, or something in another organization, which answers as not found on purpose. **What to do:** Check the IDs in the address. A resource in another organization answers as not found. **Retry the same request:** No ### method_not_allowed {#method_not_allowed} This address does not accept that HTTP method. **Why it happens:** The HTTP method does not match the address, for example PUT where only PATCH is accepted. **What to do:** Check the method in the API reference for this address. **Retry the same request:** No ### conflict {#conflict} This conflicts with something that already exists. **Why it happens:** Something with the same name already exists, or the resource's current state does not allow the change. **What to do:** Fetch the current state, resolve the conflict, then send the request again. **Retry the same request:** No ### validation_failed {#validation_failed} Some fields are missing or not valid. **Why it happens:** A required field is missing, or a value has the wrong type or format. **What to do:** Fix the fields listed in "errors" and send the request again. **Retry the same request:** No ### unprocessable {#unprocessable} The request could not be carried out as sent. **Why it happens:** The request is well-formed, but cannot be carried out in the current state of what it refers to. **What to do:** Read "message" for the reason; sending the same request again will fail the same way. **Retry the same request:** No ### range_too_large {#range_too_large} The time range is longer than this resolution allows. **Why it happens:** The time between "from" and "to" is longer than the asked resolution allows. **What to do:** Shorten the time between "from" and "to" to at most "max_range_seconds", or ask for a coarser "resolution"; "resolutions" lists the ones that would take the range you sent. **Retry the same request:** No ### rate_limited {#rate_limited} Too many requests. Slow down and try again shortly. **Why it happens:** The token sent more requests or changes than its plan allows (300 requests and 60 changes a minute, and 1000 changes an hour, by default), often a loop without a pause. "limit_key" says which. **What to do:** Wait the number of seconds in "retry_after" (also the Retry-After header), then retry. **Retry the same request:** Yes ### idempotency_key_reused {#idempotency_key_reused} This Idempotency-Key was already used for a different request. **Why it happens:** The same Idempotency-Key was sent again within 24 hours with a different method, address, query or body. **What to do:** Use a new key for every new request. Send the same key only to retry the exact same request. **Retry the same request:** No ### idempotency_in_progress {#idempotency_in_progress} A request with this Idempotency-Key is still being handled. **Why it happens:** A retry arrived while the first request with the same Idempotency-Key was still running. **What to do:** Wait a few seconds, then send the same request with the same key again to get its result. **Retry the same request:** Yes ### provider_refused {#provider_refused} The provider refused the request. **Why it happens:** The registrar, DNS or cloud provider turned the request down, most often because of an expired credential or a setting in your account there. **What to do:** Read "message" and "fix" for what the provider wants changed, usually in your account with that provider. **Retry the same request:** No ### provider_rate_limited {#provider_rate_limited} The provider is limiting requests right now. **Why it happens:** The provider is limiting how often your account with it may be called. **What to do:** Wait a minute and retry. If it keeps happening, spread the calls out. **Retry the same request:** Yes ### provider_unavailable {#provider_unavailable} The provider could not be reached or is having problems. **Why it happens:** The provider timed out or answered with an error of its own. **What to do:** Retry in a few minutes. Check status.infranest.io and the provider's own status page. **Retry the same request:** Yes ### maintenance {#maintenance} InfraNest is down for maintenance. **Why it happens:** InfraNest is being updated or maintained. **What to do:** Retry after the time in "retry_after". Check status.infranest.io for progress. **Retry the same request:** Yes ### server_error {#server_error} Something went wrong on our side. **Why it happens:** Something unexpected failed on our side. It is logged under the request's reference. **What to do:** Retry once. If it fails again, contact support and quote "reference". **Retry the same request:** Yes