Error Types

July 26, 2026 · View on GitHub

Error responses follow RFC 9457 (Problem Details for HTTP APIs) and are served with Content-Type: application/problem+json:

{
  "type": "https://github.com/KincaidYang/whois/blob/main/docs/errors.md#not-found",
  "title": "Resource not found",
  "status": 404
}

type and title are stable identifiers you can switch on; detail, when present, is human-readable context that may change between releases.

not-found

Status: 404. The domain, IP network, or ASN is not registered, or the registry returned no data for it. Not-found results are negatively cached for a short time (cache.negativeExpiration, default 60s).

The same status is returned when the query is well-formed but this service knows no WHOIS or RDAP server for its TLD — the TLD is not in the root zone, or its registry publishes neither service.

query-denied

Status: 403. The upstream registry refused to answer the query (some registries deny queries from data centers or rate-limit by source). Denied results are negatively cached like not-found.

bad-request

Status: 400. The input is not a valid domain, IP address, or ASN — or a query parameter combination is unsupported (e.g. ?raw=1 on an IP/ASN query, which has no raw WHOIS form).

unauthorized

Status: 401. The server has API key authentication enabled (auth.keys in config) and the request carried no valid key. Send a configured key as Authorization: Bearer <key> or X-API-Key: <key>. Only /health and /ready are exempt from authentication.

refresh-requires-auth

Status: 403. The ?refresh parameter (force a fresh upstream query, bypassing the cache) was used on an instance that does not have API key authentication enabled. Refresh is only honored on authenticated instances, because on an open instance it would let anyone bypass the cache and hammer upstream registries.

batch-disabled

Status: 403. The POST /batch endpoint (or the MCP batch tool) was used on an instance that has not enabled batch queries. The operator can turn them on with batch.enabled in the configuration.

rate-limited

Status: 429. Either the server's concurrent-request limit (server.rateLimit in config) was reached, or the API key's per-key rate limit (rateLimit on the key's auth.keys entry, requests per minute) is exhausted. Per-key rejections carry a Retry-After response header with the number of seconds until the next request is allowed; concurrency rejections do not, and a short delay before retrying is enough.

query-failed

Status: 500. The upstream WHOIS/RDAP query failed (network error, upstream timeout, malformed upstream response). Transient — retrying later usually succeeds. Details are logged server-side with the request's X-Request-ID.

internal-error

Status: 500. An unexpected server-side error (cache backend failure and similar). Details are logged server-side with the request's X-Request-ID.