# Error codes

Every error from the API, CLI, MCP and your app's runtime is JSON with a `code`, a `message` that says what to do, and a `docsUrl` pointing at one of these pages.

## Requests and sign-in

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`validation_failed`](/docs/errors/validation_failed) | 400 | After changing the request |
| [`confirmation_required`](/docs/errors/confirmation_required) | 400 | After changing the request |
| [`unauthenticated`](/docs/errors/unauthenticated) | 401 | After changing the request |
| [`checkout_required`](/docs/errors/checkout_required) | 403 | After a plan, setting or role change |
| [`forbidden`](/docs/errors/forbidden) | 403 | After a plan, setting or role change |
| [`two_factor_required`](/docs/errors/two_factor_required) | 403 | After changing the request |
| [`not_found`](/docs/errors/not_found) | 404 | After changing the request |
| [`conflict`](/docs/errors/conflict) | 409 | After changing the request |
| [`method_not_allowed`](/docs/errors/method_not_allowed) | 405 | After changing the request |
| [`rate_limited`](/docs/errors/rate_limited) | 429 | Yes, after the wait |
| [`feature_unavailable`](/docs/errors/feature_unavailable) | 501 | After a plan, setting or role change |
| [`internal_error`](/docs/errors/internal_error) | 500 | Yes, shortly |

## End-user sign-in

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`invalid_credentials`](/docs/errors/invalid_credentials) | 401 | After changing the request |
| [`email_not_verified`](/docs/errors/email_not_verified) | 403 | After a plan, setting or role change |
| [`email_taken`](/docs/errors/email_taken) | 409 | After changing the request |
| [`invalid_token`](/docs/errors/invalid_token) | 400 | After changing the request |
| [`sign_in_locked`](/docs/errors/sign_in_locked) | 429 | Yes, after the wait |
| [`sign_in_backoff`](/docs/errors/sign_in_backoff) | 429 | Yes, after the wait |
| [`bot_check_failed`](/docs/errors/bot_check_failed) | 403 | After changing the request |
| [`user_banned`](/docs/errors/user_banned) | 403 | After a plan, setting or role change |
| [`auth_method_disabled`](/docs/errors/auth_method_disabled) | 403 | After a plan, setting or role change |
| [`auth_not_deployed`](/docs/errors/auth_not_deployed) | 501 | After a plan, setting or role change |

## Account state

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`account_locked`](/docs/errors/account_locked) | 402 | After a plan, setting or role change |
| [`account_suspended`](/docs/errors/account_suspended) | 403 | After a plan, setting or role change |
| [`account_cancelled`](/docs/errors/account_cancelled) | 402 | After a plan, setting or role change |

## Plan counts

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`plan_limit_reached`](/docs/errors/plan_limit_reached) | 403 | After a plan, setting or role change |
| [`downgrade_blocked`](/docs/errors/downgrade_blocked) | 409 | After a plan, setting or role change |
| [`add_on_in_use`](/docs/errors/add_on_in_use) | 409 | After a plan, setting or role change |
| [`add_on_not_available`](/docs/errors/add_on_not_available) | 403 | After a plan, setting or role change |
| [`engine_not_on_plan`](/docs/errors/engine_not_on_plan) | 403 | After a plan, setting or role change |
| [`postgres_engine_required`](/docs/errors/postgres_engine_required) | 409 | After a plan, setting or role change |
| [`extension_not_supported`](/docs/errors/extension_not_supported) | 400 | After changing the request |
| [`extension_in_use`](/docs/errors/extension_in_use) | 409 | After a plan, setting or role change |
| [`parked_slots_full`](/docs/errors/parked_slots_full) | 403 | After a plan, setting or role change |
| [`park_blocked`](/docs/errors/park_blocked) | 409 | After changing the request |

## Usage limits

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`requests_capped`](/docs/errors/requests_capped) | 429 | Yes, after the wait |
| [`cpu_capped`](/docs/errors/cpu_capped) | 429 | Yes, after the wait |
| [`database_storage_full`](/docs/errors/database_storage_full) | 507 | After a plan, setting or role change |
| [`d1_size_limit`](/docs/errors/d1_size_limit) | 507 | After a plan, setting or role change |
| [`parked_limit_reached`](/docs/errors/parked_limit_reached) | 429 | After a plan, setting or role change |
| [`parked_storage_full`](/docs/errors/parked_storage_full) | 507 | After a plan, setting or role change |
| [`file_storage_full`](/docs/errors/file_storage_full) | 507 | After a plan, setting or role change |
| [`email_quota_exceeded`](/docs/errors/email_quota_exceeded) | 429 | Yes, after the wait |
| [`postgres_read_only`](/docs/errors/postgres_read_only) | 429 | Yes, after the wait |
| [`mau_capped`](/docs/errors/mau_capped) | 403 | Yes, after the wait |
| [`realtime_capacity`](/docs/errors/realtime_capacity) | 503 | Yes, after the wait |
| [`vector_records_capped`](/docs/errors/vector_records_capped) | 507 | After a plan, setting or role change |

## Email

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`email_sending_suspended`](/docs/errors/email_sending_suspended) | 403 | After a plan, setting or role change |
| [`email_rate_limited`](/docs/errors/email_rate_limited) | 429 | Yes, after the wait |
| [`email_too_many_recipients`](/docs/errors/email_too_many_recipients) | 400 | After changing the request |
| [`email_send_failed`](/docs/errors/email_send_failed) | 502 | Yes, shortly |
| [`email_appeal_not_open`](/docs/errors/email_appeal_not_open) | 409 | After a plan, setting or role change |

## Sender domains

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`email_domain_invalid`](/docs/errors/email_domain_invalid) | 400 | After changing the request |
| [`email_domain_not_verified`](/docs/errors/email_domain_not_verified) | 422 | After a plan, setting or role change |

## AI gateway

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`ai_user_cap_reached`](/docs/errors/ai_user_cap_reached) | 429 | Yes, after the wait |
| [`ai_project_cap_reached`](/docs/errors/ai_project_cap_reached) | 429 | Yes, after the wait |
| [`ai_credit_exhausted`](/docs/errors/ai_credit_exhausted) | 402 | After a plan, setting or role change |

## Projects and domains

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`not_deployed`](/docs/errors/not_deployed) | 503 | After a plan, setting or role change |
| [`project_provisioning`](/docs/errors/project_provisioning) | 409 | Yes, after the wait |
| [`project_deleted`](/docs/errors/project_deleted) | 410 | After a plan, setting or role change |
| [`project_archived`](/docs/errors/project_archived) | 409 | After a plan, setting or role change |
| [`archive_blocked`](/docs/errors/archive_blocked) | 409 | After changing the request |
| [`no_free_slot`](/docs/errors/no_free_slot) | 403 | After a plan, setting or role change |
| [`export_expired`](/docs/errors/export_expired) | 410 | After changing the request |
| [`domain_taken`](/docs/errors/domain_taken) | 409 | After a plan, setting or role change |

## Outbound requests

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`outbound_blocked`](/docs/errors/outbound_blocked) | 403 | After changing the request |
| [`edge_unavailable`](/docs/errors/edge_unavailable) | 503 | Yes, shortly |

## Sandboxes

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`sandbox_rate_limited`](/docs/errors/sandbox_rate_limited) | 429 | Yes, after the wait |
| [`sandbox_expired`](/docs/errors/sandbox_expired) | 410 | After a plan, setting or role change |

## Cron

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`cron_timeout`](/docs/errors/cron_timeout) | 504 | After changing the request |
| [`cron_interval_too_short`](/docs/errors/cron_interval_too_short) | 422 | After changing the request |

## Imports

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`import_source_unreachable`](/docs/errors/import_source_unreachable) | 502 | After changing the request |
| [`import_blocked`](/docs/errors/import_blocked) | 422 | After changing the request |
| [`import_running`](/docs/errors/import_running) | 409 | Yes, after the wait |
| [`import_expired`](/docs/errors/import_expired) | 409 | After a plan, setting or role change |

## Deploys and migrations

| Code | HTTP | Retrying helps |
| --- | --- | --- |
| [`deploy_failed`](/docs/errors/deploy_failed) | 422 | After changing the request |
| [`destructive_migration`](/docs/errors/destructive_migration) | 409 | After changing the request |
| [`migration_failed`](/docs/errors/migration_failed) | 422 | After changing the request |
| [`migration_conflict`](/docs/errors/migration_conflict) | 409 | After changing the request |
| [`bundle_too_large`](/docs/errors/bundle_too_large) | 413 | After changing the request |
| [`assets_too_large`](/docs/errors/assets_too_large) | 413 | After changing the request |
| [`assets_missing`](/docs/errors/assets_missing) | 409 | After changing the request |
| [`publish_too_large`](/docs/errors/publish_too_large) | 413 | After changing the request |
| [`deploy_blocked_by_scanner`](/docs/errors/deploy_blocked_by_scanner) | 422 | After changing the request |