---
title: Handle Errors and Rate Limits
sidebarTitle: Errors & Rate Limits
description: The error envelope, what each status class means, and which failures are worth retrying
---

Every documented error uses the same three-field JSON envelope:

```json
{
  "code": "invalid_param",
  "message": "user is required",
  "status": 400
}
```

`status` mirrors the HTTP status; `code` is the stable identifier to branch on; `message` is human-readable detail. Each endpoint page lists exactly which codes it can raise.

## Status Classes at a Glance

| Status | Meaning | Typical codes |
|:-------|:--------|:--------------|
| 400 | The request or the app's configuration is invalid | `invalid_param`, `bad_request`, `app_unavailable`, provider errors (below) |
| 401 | Missing or invalid API key | `unauthorized` |
| 403 | The key can't act here: access restrictions or plan limits | `forbidden` |
| 404 | The resource doesn't exist or isn't visible to this key or `user` | `not_found` |
| 413 / 415 | A file is too large or of an unsupported type | `file_too_large`, `unsupported_file_type` |
| 429 | Too many requests right now, or a quota is exhausted | `too_many_requests`, `rate_limit_error` |
| 500 | Something failed on Dify's side | `internal_server_error` |

## Provider Errors Are Configuration Errors

Four common 400 codes point at the app's model setup rather than your request:

- `provider_not_initialize`: no valid model credentials
- `provider_quota_exceeded`: the model provider's own quota ran out
- `model_currently_not_support`: the model isn't currently supported
- `completion_request_error`: an error occurred while making a completion request

For these errors, retrying won't help. Fix the app's model configuration in Dify.

## Rate Limits and Quotas

The two 429 codes mean different things:

- `too_many_requests` is a concurrency ceiling—too many simultaneous requests for the app right now. Back off and retry.
- `rate_limit_error` is a plan quota on Dify Cloud, such as workflow executions. Retrying won't clear it; it resets with the quota period or a plan change.

On Dify Cloud, knowledge write endpoints also enforce plan limits as `403` responses. These carry the same `forbidden` code as access restrictions—the `message` is what tells you it's a plan limit, so don't build a switch on `code` alone for 403s.

## Errors Inside Streams

Once a stream opens, the HTTP status is already `200`: failures arrive as an `error` event and end the stream. The event's `code` values are the same ones documented here—classify them with the same rules. See [Consume Streaming Responses](/en/api-reference/guides/streaming) for details.

## What to Retry

- **Retry with backoff**: `too_many_requests`, `500`, and network failures.

- **Don't retry as-is**: validation errors (fix the request first), authorization failures, or quota errors (they won't clear until the quota does).
- **Fix, don't retry**: a `404` from a resume call means the wrong `user` or a run that doesn't exist. Correct the identifier instead.