Ferra.rs / Docs / Error Types

Error type URIs

Every Ferra error response carries an RFC 7807 body whose type field is one of these nine URIs. The set is closed — no URI outside this table will ever appear on the wire.

Variant HTTP status Title Source
not_found 404 Not Found Resource Not Found FerraError::NotFound
validation 400 Bad Request Validation Error FerraError::Validation
validation_failed 422 Unprocessable Content Validation Failed FerraError::Unprocessable
conflict 409 Conflict Conflict FerraError::Conflict
internal 500 Internal Server Error Internal Server Error FerraError::Internal
payload_too_large 413 Payload Too Large Payload Too Large request-body-limit middleware
rate_limited 429 Too Many Requests Too Many Requests rate-limit middleware
unauthorized 401 Unauthorized Unauthorized Foundry::with_docs_protected(…)
invalid_cursor 400 Bad Request Invalid Cursor FerraError::InvalidCursor

not_found

Resource Not Found

404 Not Found

Returned by every read, update, or delete operation that resolves to zero matching rows.

{
  "type":   "https://ferra.rs/errors/not_found",
  "title":  "Resource Not Found",
  "status": 404,
  "detail": "films/c2bb1f10-72b8-486a-9f2b-c92e4a2cdf41 not found"
}
Full documentation →

validation

Validation Error

400 Bad Request

Returned when an inbound JSON body fails to parse or a path parameter cannot be deserialised. The errors map contains a single entry keyed by "body" or "id". For #[field(…)] rule failures on a valid body, see validation_failed (422).

{
  "type":   "https://ferra.rs/errors/validation",
  "title":  "Validation Error",
  "status": 400,
  "detail": "validation failed",
  "errors": {
    "body": ["invalid character '}' at line 1 column 12"]
  }
}
Full documentation →

validation_failed

Validation Failed

422 Unprocessable Content

Returned when a well-formed JSON body deserialises into the model's request shape but one or more #[field(…)] rule constraints fail. Every violation is reported — the framework never short-circuits on the first error. Distinct from validation (400), which fires when the body cannot be parsed at all.

{
  "type":   "https://ferra.rs/errors/validation_failed",
  "title":  "Validation Failed",
  "status": 422,
  "detail": "validation failed",
  "errors": {
    "title":  ["must be at least 1 character"],
    "rating": ["must be at most 10"]
  }
}
Full documentation →

conflict

Conflict

409 Conflict

Returned when a write would violate a unique constraint — a duplicate slug, primary-key collision, or similar.

{
  "type":   "https://ferra.rs/errors/conflict",
  "title":  "Conflict",
  "status": 409,
  "detail": "title 'Casablanca' is already in use"
}
Full documentation →

internal

Internal Server Error

500 Internal Server Error

Returned for any database or infrastructure failure not classifiable as one of the typed variants above. The detail field is always the constant literal "internal server error" — no internal path, crate name, or library substring is ever leaked.

{
  "type":   "https://ferra.rs/errors/internal",
  "title":  "Internal Server Error",
  "status": 500,
  "detail": "internal server error"
}
Full documentation →

payload_too_large

Payload Too Large

413 Payload Too Large

Emitted when an inbound request body exceeds the framework's default 1 MiB cap (DoS protection). Emitted by the request-body-limit middleware, not through FerraError.

{
  "type":   "https://ferra.rs/errors/payload_too_large",
  "title":  "Payload Too Large",
  "status": 413,
  "detail": "request body too large"
}
Full documentation →

rate_limited

Too Many Requests

429 Too Many Requests

Emitted by the framework's default rate-limiter on mutation routes (POST / PUT / DELETE). The response carries a Retry-After header when the limiter can compute a sensible delay.

{
  "type":   "https://ferra.rs/errors/rate_limited",
  "title":  "Too Many Requests",
  "status": 429,
  "detail": "rate limit exceeded"
}
Full documentation →

unauthorized

Unauthorized

401 Unauthorized

Emitted by Foundry::with_docs_protected(verifier) when an unauthenticated request reaches the docs surface. New in v0.5.0.

{
  "type":   "https://ferra.rs/errors/unauthorized",
  "title":  "Unauthorized",
  "status": 401,
  "detail": "authentication required"
}
Full documentation →

invalid_cursor

Invalid Cursor

400 Bad Request

Returned when a ?cursor=… query parameter cannot be decoded into a valid keyset-pagination token. The detail field is a fixed literal — the framework never echoes the bytes of the malformed cursor back to the client (no reflection oracle). Recovery: drop cursor and restart pagination. New in v0.7.5.

{
  "type":   "https://ferra.rs/errors/invalid_cursor",
  "title":  "Invalid Cursor",
  "status": 400,
  "detail": "the supplied cursor token is invalid; drop the `cursor` query parameter and restart pagination"
}
Full documentation →