# Error codes

Every error is `{"error":{"code","message","hint?","docs_url?"}}`. Codes never
change meaning.

| code | HTTP | meaning | what to do |
|---|---|---|---|
| `unauthorized` | 401 | missing, expired or revoked token | `rapadura login` |
| `forbidden` | 403 | token lacks the scope, or owner role required | use a publish token / ask the owner |
| `login_unavailable` | 503 | GitHub login not enabled on the gateway yet | ask the owner for a token (`RAPADURA_TOKEN`) |
| `not_invited` | 403 | GitHub user has no invite | owner runs `rapadura admin invite <login>` |
| `not_found` | 404 | no such site, version or token you can see | check `rapadura sites list` |
| `invalid_request` | 400 | malformed input | read the message |
| `invalid_slug` | 400 | slug has bad characters, length or `--` | lowercase, digits, single hyphens |
| `slug_reserved` | 409 | slug is reserved (www, mail, panel, …) | pick another |
| `slug_taken` | 409 | hostname exists, is held after deletion, or belongs to another site on the server | pick another |
| `zone_unknown` | 400 | zone not served | `rapadura zones` |
| `quota_exceeded` | 429 | too many sites for this user | delete one or ask the owner |
| `archive_forbidden_file` | 400 | credentials or server-side code in the upload | publish only the public output directory |
| `archive_invalid` | 400 | not a zip, unsafe paths, symlinks, or empty | rebuild the archive |
| `archive_too_large` | 413 | over the size limit | `rapadura zones` shows limits |
| `publish_failed` | 500 | nginx refused the config or verification failed; previous version kept | read the message, retry, or report to the owner |
| `wp_refused` | 403 | the wp-cli command or flag is outside the staff policy | read the message; ask the owner to allow it |
| `wp_unavailable` | 503 | the WordPress lane is not enabled on this gateway | ask the owner |
| `rate_limited` | 429 | too many requests | wait a minute |
| `device_pending` | 202 | login not yet approved | keep polling |
| `device_denied` | 403 | login denied on GitHub | run login again |
| `device_expired` | 410 | login code expired or already used | run login again |
| `internal` | 500 | unexpected | report to the owner with the time |
