> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squarecloud.app/llms.txt
> Use this file to discover all available pages before exploring further.

# API error codes and how to fix them

> Every error code the Square Cloud API returns, grouped by area, with its HTTP status, what it means and what to do next, plus the rules for retries.

Every failed request to the Square Cloud API answers with an HTTP status and a JSON body that carries a machine-readable `code`. This page lists every code, grouped by area. Each endpoint page also lists the codes that endpoint returns most often.

<Note>
  [Blob Storage](/en/blob-reference/errors) has its own list of codes, and the [AI Gateway](/en/api-reference/ai-gateway#errors) answers in the OpenAI error format with lowercase codes. Neither is covered here.
</Note>

## Error format

```json theme={"system"}
{
  "status": "error",
  "code": "APP_NOT_FOUND",
  "message": "Optional explanation for humans."
}
```

| Field | Description |
| - | - |
| `status` | Always `"error"` on a failure. |
| `code` | The error code, in `UPPER_SNAKE_CASE`. Branch on this field. |
| `message` | Optional. A human-readable explanation that may change at any time, so show it to people but never parse it. |

<Info>
  The list of codes grows over time. Treat a code you don't know as a generic failure of the HTTP status it came with: fix the request on a `4xx`, wait on a `429`, and retry later on a `5xx`.
</Info>

## Retries

The API sends no `Retry-After` header, so the decision is yours. A safe policy:

| Answer | What to do |
| - | - |
| `400`, `401`, `403`, `404`, `409`, `413`, `415` | Don't retry the same request: it fails the same way. Fix the input, the credential or the plan first. |
| `429` | Wait before the next request. Retrying in a loop keeps you blocked. See [Rate limits](#rate-limits). |
| `503 UPLOAD_BUSY`, `503 ANALYTICS_BUSY` | Retry after a short pause, with exponential backoff. |
| `503 DATABASE_UNAVAILABLE` | Retry a read after a few seconds. A write may already have been applied, so check the resource before you repeat it. |
| `500` and other `5xx` | Retry once or twice with backoff. If it keeps failing, check the [service status](/en/api-reference/endpoint/service/status). |

`202 SNAPSHOT_PROCESSING` keeps the error envelope for compatibility, but it is **not a failure**: the snapshot is still being generated and shows up in the listing on its own. Don't request it again.

## Rate limits

Two codes answer `429`, and they mean different things:

* **`RATE_LIMITED`**: the request budget of your account or API key, counted per 60 seconds and set by your plan (see the [per-plan values](/en/api-reference/limitations-and-restrictions#api-limits)). Past it, the API refuses your requests for up to 30 minutes. A few endpoints also answer `RATE_LIMITED` for their own limits, and an IP address that keeps sending API keys that belong to no account is blocked for a short period.
* **`KEEP_CALM`**: one endpoint's own limit, such as one restart every few seconds. Wait a moment and try again. The limit of each endpoint is on its page.

## Authentication and permissions

| Code | HTTP | Meaning and fix |
| - | - | - |
| `ACCESS_DENIED` | 401 | The API key is missing, mistyped, revoked or expired, or its account no longer exists. Check the key in your [account security settings](https://squarecloud.app/en/account/security) and don't retry in a loop. |
| `MISSING_SCOPE` | 403 | The key is valid but lacks the scope this endpoint needs. Scopes can't be edited, so create a key with that scope. See [Scopes](/en/api-reference/authentication#scopes). |
| `RESOURCE_NOT_ALLOWED` | 403 | The key is restricted to applications and databases that don't include this one, or the endpoint is account-wide and the key is restricted. Use a key that covers the resource. |
| `PERMISSION_DENIED` | 403 | Your workspace role doesn't allow this action on a shared application, such as reading `.env` without the `admin` role. See [workspace roles](/en/api-reference/endpoint/workspace/members/invite#roles). |
| `SCOPE_NOT_GRANTABLE` | 403 | A restricted API key tried to grant more access than it holds, for example adding an `admin` member with a key that lacks `envs:write`. Use a key that holds every scope of that role, or the dashboard. |
| `UPGRADE_REQUIRED` | 402 / 403 | The feature needs a higher plan: databases, custom domains and workspaces need Standard or above, network logs and performance need Pro or above, and listing account snapshots needs an active plan (`402`). The `message` names the plan when it can. |

## Request validation

| Code | HTTP | Meaning and fix |
| - | - | - |
| `INVALID_JSON_BODY` | 400 | The body is not valid JSON. Send `Content-Type: application/json` and a well-formed body. |
| `INVALID_INPUT` | 400 | A field failed validation. The `message` says which. |
| `INVALID_ID` | 400 | A required id, usually `workspaceId`, is missing or malformed. |
| `INVALID_CONTENT_TYPE` | 415 | Upload and commit need `multipart/form-data` with the zip in a `file` field. |
| `PAYLOAD_TOO_LARGE` | 413 | The body is larger than this endpoint accepts. |
| `ROUTE_NOT_FOUND` | 404 | The path or the HTTP method is wrong. Compare it with the endpoint page. |

## Quotas and connection limits

| Code | HTTP | Meaning and fix |
| - | - | - |
| `RATE_LIMITED` | 429 | The request budget of your account or key was reached, or an endpoint's own limit. See [Rate limits](#rate-limits). |
| `KEEP_CALM` | 429 | Too many requests to this endpoint in a short time. Wait a moment and retry. |
| `DAILY_SNAPSHOTS_LIMIT_REACHED` | 429 | The plan's allowance of manual snapshots per 24 hours is used up. Wait before the next one, or upgrade for a larger allowance. |
| `REALTIME_MAX_CONNECTIONS` | 429 | Your account already has 5 [realtime](/en/api-reference/endpoint/apps/realtime) connections open. Close one first. |
| `REALTIME_MAX_CONNECTIONS_APP` | 429 | The application already has 30 realtime connections open across all users. |

## Applications

| Code | HTTP | Meaning and fix |
| - | - | - |
| `APP_NOT_FOUND` | 404 | The application doesn't exist, isn't yours, or you are not a member of the workspace it is shared in. Check the id. Workspace routes answer `400` when `appId` is missing from the body. |
| `CONTAINER_ALREADY_STARTED` | 409 | The application or database is already running. You can treat it as a success. |
| `CONTAINER_ALREADY_STOPPED` | 409 | The application or database is already stopped. You can treat it as a success. |
| `CONTAINER_TEMPORARILY_SUSPENDED` | 409 | The resource is suspended. Check the email of the account for the reason. |
| `CONTAINER_NOT_FOUND` | 409 | The resource's container wasn't found on its server. Try again in a moment, and contact support if it persists. |
| `CONTAINER_INSUFFICIENT_DISK_SPACE` | 409 | There isn't enough disk space to start. Remove files you don't need and try again. |
| `CONTAINER_NETWORK_CONFLICT` | 409 | A network or port conflict stopped the start. Try again in a moment. |
| `ACTION_FAILED` | 409 | The start, stop or restart was refused for another reason, for example during a deploy. Check the status and retry. |
| `RESTORE_IN_PROGRESS` | 403 | A snapshot restore is running on this resource. Wait for it to finish before you delete the application, or start, stop or delete the database. |
| `DELETE_FAILED` | 404 | The node that hosts the resource refused the deletion. Retry. On the file manager, the same code answers `400`. |
| `LOGS_UNAVAILABLE` | 404 | The logs couldn't be read: the application is offline, was never deployed, or the node didn't answer. Retry shortly. |
| `METRICS_NOT_SUPPORTED` | 400 | Metrics are collected only for applications with at least 512 MB of RAM. |

## Upload and commit

| Code | HTTP | Meaning and fix |
| - | - | - |
| `INVALID_FILE` | 400 | The form has no file in the `file` field. |
| `INVALID_FILENAME` | 400 | The file name has path separators, `..` or control characters. |
| `INVALID_PATH` | 400 | The `path` of a commit contains traversal or shell characters. |
| `FILE_TOO_LARGE` | 413 | The zip is over 100 MB. |
| `UPLOAD_ABORTED` | 400 | The connection closed before the upload finished. Upload again. |
| `UPLOAD_BUSY` | 503 | Too many uploads are in progress on the platform. Retry after a short pause. |
| `STORAGE_UPLOAD_FAILED` | 400 | The zip couldn't be stored. Retry later. |
| `UPLOAD_FAILED` | 400 | The upload couldn't be processed. Retry, and check the zip if it happens again. |
| `COMMIT_FAILED` | 400 | The commit couldn't be applied. Retry, and check the zip if it happens again. |
| `INSUFFICIENT_MEMORY` | 400 | Your plan doesn't have enough free memory for the application or database, or `MEMORY` is below the minimum: 256 MB, or 512 MB for a website with a `SUBDOMAIN`. Adjust `MEMORY`, delete something, or upgrade. |
| `CLUSTER_SELECTION_FAILED` | 400 | No server had room for the new application or database right now. Retry later. |
| `CLUSTER_MAINTENANCE_TRY_LATER` | 503 | New applications and databases are paused for maintenance. Retry later. |
| `EMPTY_RESPONSE` | 400 | The server that received the upload gave no usable answer, so the application was not created. Upload again. |

## Zip and configuration checks

When you [upload](/en/api-reference/endpoint/apps/upload) an application, the server that will run it checks the zip and its [configuration file](/en/getting-started/config-file) (`squarecloud.app` or `squarecloud.config`). A failed check answers `400` with one of these codes, and nothing is deployed. Fix the zip and upload it again. A [commit](/en/api-reference/endpoint/apps/commit) doesn't read the configuration file: it can only fail with `FAILED_EXTRACT` or `CONTAINER_INSUFFICIENT_DISK_SPACE` from this list.

| Code | HTTP | Meaning and fix |
| - | - | - |
| `FAILED_EXTRACT` | 400 | The zip couldn't be extracted. Create it again with a standard zip tool and check that it isn't damaged. |
| `DOWNLOAD_FAILED` | 400 | The server couldn't fetch the zip after it was received. Upload again. |
| `MISSING_CONFIG` | 400 | The zip has no `squarecloud.app` or `squarecloud.config` at its root, or the file is empty. |
| `MISSING_MEMORY`, `MISSING_DISPLAY_NAME`, `MISSING_VERSION` | 400 | A required field of the configuration file is missing or empty. The code names the first one missing. |
| `MISSING_MAIN` | 400 | The configuration has neither [`MAIN`](/en/getting-started/config-file#main) nor [`RUNTIME`](/en/getting-started/config-file#runtime). Set one of them. |
| `INVALID_MAIN` | 400 | `MAIN` has characters other than letters, digits, `_`, `.`, `/` and `-`, or more than 32 characters. Without `RUNTIME`, it also fails when the file isn't in the zip, is empty, points outside the project, or has no extension or one that matches no supported language. |
| `INVALID_RUNTIME` | 400 | `RUNTIME` is not one of the supported values listed in the [configuration file](/en/getting-started/config-file#runtime) reference. |
| `INVALID_VERSION` | 400 | `VERSION` must be `recommended` or `latest`. An exact version number is refused. |
| `INVALID_START` | 400 | `START` is longer than 256 characters. |
| `INVALID_DEPENDENCY` | 400 | The dependency file of the language is missing or empty: `package.json` for JavaScript and TypeScript, `requirements.txt` or `pyproject.toml` for Python, `go.mod` or `go.work` for Go, `Cargo.toml` for Rust, `Gemfile` for Ruby, `mix.exs` for Elixir. |
| `INVALID_DISPLAY_NAME` | 400 | `DISPLAY_NAME` must have 1 to 32 characters: letters, digits, spaces, `_` and `-`. |
| `INVALID_DESCRIPTION` | 400 | `DESCRIPTION` is longer than 280 characters. |
| `INVALID_SUBDOMAIN` | 400 | `SUBDOMAIN` is malformed, reserved or already taken. Pick another. |
| `CONTAINER_INSUFFICIENT_DISK_SPACE` | 400 | On a commit, there isn't enough disk space for the new files. Delete files you don't need and commit again. |
| `ACCESS_FORBIDDEN` | 400 | The server couldn't load your account for this upload. Retry, and contact support if it persists. |

## Environment variables

| Code | HTTP | Meaning and fix |
| - | - | - |
| `STATIC_APP_ENV_NOT_SUPPORTED` | 400 | Static sites don't support environment variables. |
| `INVALID_ENV_CONTENT` | 400 | `envs` is missing or has the wrong shape: an object to add or replace, an array of keys to remove. |
| `TOO_MANY_ENV_VARS` | 400 | The application would have more than 256 variables. |
| `ENV_NAME_TOO_LONG` | 400 | A key is longer than 1024 characters, or is not a string. |
| `ENV_CONTENT_TOO_LONG` | 400 | A value is longer than 4096 characters. |
| `READ_FAILED` | 400 | The variables couldn't be read from the application. Retry. The certificate route uses the same code. |

## Files

| Code | HTTP | Meaning and fix |
| - | - | - |
| `INVALID_PATH` | 400 | The path has traversal or invalid characters, is longer than 256 characters, or the source and destination of a move are the same. |
| `BLOCKED_PATH` | 403 | The path is in a protected directory, or your workspace role can't write that file. |
| `INVALID_ENCODING` | 400 | `encoding` accepts only `base64`. |
| `INVALID_CONTENT` | 400 | `content` is missing, has an unsupported shape, or isn't valid base64. |
| `FILE_NOT_FOUND` | 404 | There is no file or directory at that path. |
| `FILE_TOO_LARGE` | 413 | The file manager reads and writes files of up to 10 MB. Use [commit](/en/api-reference/endpoint/apps/commit) for bigger files. |
| `RENAME_FAILED` | 400 | The file couldn't be moved or renamed. Retry. |
| `DELETE_FAILED` | 400 | The file couldn't be deleted. Retry. |
| `INVALID_DISPLAY_NAME`, `INVALID_DESCRIPTION`, `INVALID_MEMORY`, `INVALID_AUTORESTART`, `INVALID_SUBDOMAIN` | 400 | A write to the [configuration file](/en/getting-started/config-file) has a field that fails validation, or a `SUBDOMAIN` that is already taken. Fix that field. |
| `CANNOT_SET_SUBDOMAIN` | 400 | The configuration of a website has no `SUBDOMAIN`. A website always keeps one, so set it back. |
| `SAVE_FAILED` | 500 | The new configuration couldn't be saved. Retry. |

## Deploys and GitHub

| Code | HTTP | Meaning and fix |
| - | - | - |
| `INVALID_ACCESS_TOKEN` | 400 | The webhook token is neither a GitHub token (`ghp_...`, `github_pat_...`) nor `@`. |
| `MISSING_REQUIRED_FIELDS` | 400 | `repositoryName` or `repositoryBranch` is missing. |
| `INVALID_BRANCH_LENGTH` | 400 | The branch name is longer than 256 characters. |
| `BRANCH_NOT_FOUND` | 400 | The branch doesn't exist in the repository. |
| `GIT_ALREADY_CONFIGURED` | 400 | The application already has a linked repository. Unlink it first. |
| `GIT_NOT_CONFIGURED` | 400 | The application has no linked repository to unlink. |
| `GITHUB_NOT_CONNECTED` | 403 | Your Square Cloud account has no working GitHub connection. Connect or reconnect GitHub in the dashboard. |
| `REPOSITORY_NOT_AVAILABLE` | 403 | The Square Cloud GitHub App isn't installed on the repository through your GitHub account. |
| `REPOSITORY_PERMISSION_REQUIRED` | 403 | Your GitHub account needs write access to the repository. |
| `REPOSITORY_NOT_FOUND` | 404 | The repository doesn't exist or your GitHub account can't see it. |
| `REPOSITORY_BRANCH_ALREADY_CONFIGURED` | 409 | Another application, of any account, already uses this repository and branch. |
| `FAILED_TO_FETCH` | 502 | GitHub didn't confirm the branch. Retry. |
| `VALIDATION_FAILED` | 500 / 502 | The repository couldn't be validated. Retry. |
| `VALIDATION_TIMEOUT` | 504 | Validating the repository took too long. Retry. |

A failed Git deploy is not an HTTP error: it shows up in the [deploy history](/en/api-reference/endpoint/apps/deploy/list) as an event with `state: "error"` and a `code` such as `DEPLOY_FAILED`.

## Network and domains

| Code | HTTP | Meaning and fix |
| - | - | - |
| `INVALID_TIME_RANGE` | 400 | `start` or `end` is missing or malformed, or `start` is after `end`. |
| `INVALID_FILTER` | 400 | A filter of the analytics endpoint has the wrong format. |
| `UNABLE_TO_FETCH_ANALYTICS`, `UNABLE_TO_FETCH_ERRORS`, `UNABLE_TO_FETCH_PERFORMANCE` | 500 | The edge provider didn't return the data. Retry later. |
| `ANALYTICS_BUSY` | 503 | Network analytics are busy across the platform. Retry after a short pause. |
| `NO_CUSTOM_DOMAIN` | 400 | The application has no custom domain, so it has no DNS records to show. |
| `INVALID_DOMAIN` | 400 | The value is not a valid domain name. |
| `RESERVED_DOMAIN` | 400 | Square Cloud's own domains and their subdomains can't be used as a custom domain. |
| `DOMAIN_ALREADY_EXISTS` | 409 | Another account already uses this domain. Remove it there first. |
| `LOAD_BALANCER_LIMIT_REACHED` | 403 | Your plan doesn't allow this domain on more applications. The `message` gives the limit. |
| `DNS_FAILED` | 502 | The edge provider couldn't attach the domain. Your previous domain stays in place. Retry. |
| `PURGE_CACHE_FAILED` | 500 | The cache purge didn't complete. Retry in a moment. |

## Snapshots

| Code | HTTP | Meaning and fix |
| - | - | - |
| `SNAPSHOT_PROCESSING` | 202 | Not an error: the snapshot is still being generated. Check the listing in a couple of minutes. |
| `SNAPSHOT_FAILED` | 404 | The snapshot couldn't be created. Retry later. |
| `MISSING_PARAMETERS` | 400 | `snapshotId` or `versionId` is missing. |
| `INVALID_SNAPSHOT_ID` | 400 | `snapshotId` is not a `name` from the snapshot listing. |
| `INVALID_VERSION_ID` | 400 | `versionId` is not a `version_id` from the snapshot listing. |
| `SNAPSHOT_NOT_FOUND` | 404 | No snapshot matches that id and version. |
| `SNAPSHOT_RESTORE_FAILED` | 404 | The restore failed. Retry, or restore another snapshot. |
| `SNAPSHOT_DATABASE_MISMATCH` | 400 | The snapshot is from a different database engine than the target database. |
| `INVALID_SCOPE` | 400 | The `scope` of the account snapshot listing must be `applications` or `databases`. |

## Databases

| Code | HTTP | Meaning and fix |
| - | - | - |
| `DATABASE_NOT_FOUND` | 404 | The database doesn't exist or isn't yours. |
| `INVALID_NAME` | 400 | The name must have 1 to 32 characters. Workspaces follow the same rule. |
| `INVALID_DATABASE_TYPE` | 400 | `type` must be `mongo`, `mysql`, `postgres` or `redis`. |
| `INVALID_DATABASE_VERSION` | 400 | The version isn't available for that engine. |
| `INVALID_MEMORY` | 400 | The memory isn't valid for this engine or plan. |
| `DATABASE_CREATION_FAILED` | 400 / 500 | The database couldn't be created. Nothing was left behind, so you can retry. |
| `DATABASE_NOT_RUNNING` | 400 | Start the database before you read its certificate or reset its credentials. |
| `INVALID_RESET_TYPE` | 400 | `reset` must be `password` or `certificate`. |
| `RESET_FAILED` | 500 | The credentials couldn't be reset. Retry. |
| `NO_UPDATE_DATA` | 400 | Send `name`, `ram` or both to update a database. |

## Workspaces

| Code | HTTP | Meaning and fix |
| - | - | - |
| `WORKSPACE_NOT_FOUND` | 404 | The workspace doesn't exist, or you are neither its owner nor a member. |
| `WORKSPACE_LIMIT_REACHED` | 400 | Your account already has the most workspaces its plan allows. |
| `WORKSPACE_CREATION_FAILED` | 400 | The workspace couldn't be created. Retry. |
| `INVALID_CODE` | 400 | The invite code is missing, malformed or expired. Ask the person for a new one. |
| `INVALID_GROUP` | 400 | `group` must be `view`, `manager`, `maintain` or `admin`. |
| `CANNOT_INVITE_OWNER` | 400 | The invite code is yours, and you already own the workspace. |
| `CANNOT_EDIT_OWNER` | 400 | The owner's role can't be changed. |
| `CANNOT_LEAVE_OWNER` | 400 | The owner can't leave the workspace. Delete it instead. |
| `MEMBERS_LIMIT_REACHED` | 400 | The workspace already has the most members the owner's plan allows. |
| `MEMBER_ALREADY_ADDED` | 400 | That person is already a member. |
| `MEMBER_NOT_FOUND` | 400 / 404 | `memberId` is missing (`400`) or that person isn't a member anymore (`404`). |
| `APPLICATIONS_LIMIT_REACHED` | 400 | The workspace already shares 100 applications. |
| `APP_ALREADY_IN_WORKSPACE` | 400 | The application is already shared in this workspace. |

## Platform

| Code | HTTP | Meaning and fix |
| - | - | - |
| `INTERNAL_SERVER_ERROR` | 500 | An unexpected failure. Retry once, and contact support if it persists. |
| `DATABASE_UNAVAILABLE` | 503 | The platform database is briefly unavailable. Retry in a few seconds. An existing resource is never reported as not found in this state. |
| `CLUSTER_TIMEOUT` | 400 | The server that hosts the resource didn't answer in time. Retry. |
| `CLUSTER_UNAVAILABLE` | 400 | The server that hosts the resource can't be reached right now. Retry shortly. |
| `REQUEST_ABORTED` | 400 | The request was cancelled before the server that hosts the resource answered. Retry. |
| `INVALID_PARAMETERS` | 400 | An internal request was malformed. Retry, and contact support if it persists. |

<Note>
  The `AI_*` codes (`AI_DAILY_LIMIT_REACHED`, `AI_NO_PLAN_LIMIT_REACHED`, `AI_MAX_CONCURRENT_STREAMS`, `AI_UNAVAILABLE`) belong to the dashboard's AI assistant, which needs a dashboard session. An API key never receives them.
</Note>

## Related

* [Authentication and scopes](/en/api-reference/authentication)
* [Rate limits per plan](/en/api-reference/limitations-and-restrictions)
* JavaScript SDK: [`SquareCloudAPIError`](/en/sdks/js/errors)
* Python SDK: [`SquareCloudAPIError`](/en/sdks/py/errors)
* Go SDK: [`*APIError`](/en/sdks/go/errors)
