Skip to content

Error Codes

All errors return a JSON body:

{ "error": "Human-readable error message" }

Internal errors (500) return a generic message to prevent information leakage. The actual error is logged server-side.

HTTP StatusMeaningWhen
400Bad RequestInvalid input, malformed JSON, validation failure
401UnauthorizedMissing, invalid, or expired token
403ForbiddenAuthenticated but not allowed (e.g., insufficient role)
404Not FoundFile, directory, or upload not found
409ConflictFile already exists (rename without overwrite), TUS offset mismatch
410GoneSetup window has expired
428Precondition RequiredSetup must be completed before this operation
429Too Many RequestsRate limit exceeded — login (10 per 15 min per IP) or API endpoints (search, thumbnails, HLS — default 60 per min per IP)
500Internal Server ErrorDatabase, I/O, or unexpected error (details logged, not returned)

Your token has expired. Call POST /api/auth/refresh to get a new one, or re-login. The web UI handles this automatically — a 401 on any non-auth endpoint triggers a logout.

The Upload-Offset header doesn’t match the server’s current offset. Query the offset with HEAD /api/tus/{id} and resume from the returned value.

The setup window has expired. Delete rustyfile.db from your data directory and restart to re-open it.

Rate limit hit. Wait up to 15 minutes or try from a different IP. The rate limiter uses a leaky bucket algorithm — the window refills gradually, not all at once.