Skip to main content
ofetch includes built-in retry logic for failed requests, automatically retrying requests that fail with specific status codes.

Default Retry Behavior

By default, ofetch retries failed requests once for safe methods (GET, HEAD, OPTIONS, TRACE):
Methods that may have side effects (POST, PUT, PATCH, DELETE) are not retried by default to avoid unintended duplicate operations.
Retries only occur when the response status code matches one of the retryable status codes. Network errors and timeouts are also retried.

Retry Status Codes

The following HTTP status codes trigger automatic retries:
  • 408 - Request Timeout
  • 409 - Conflict
  • 425 - Too Early (Experimental)
  • 429 - Too Many Requests
  • 500 - Internal Server Error
  • 502 - Bad Gateway
  • 503 - Service Unavailable
  • 504 - Gateway Timeout
These status codes typically indicate temporary issues that may succeed on retry.

Configuring Retry Count

You can customize the number of retry attempts using the retry option:
number | false
default:"1 for safe methods, 0 for unsafe methods"
The number of times to retry the request. Set to false to disable retries completely.

Retry Delay

You can add a delay between retry attempts:
number | ((context: FetchContext) => number)
default:"0"
Delay in milliseconds between retry attempts. Can be a fixed number or a function that returns the delay based on the fetch context.

Fixed Delay

Dynamic Delay (Exponential Backoff)

Retry with Jitter

Custom Retry Status Codes

You can override the default retry status codes:
number[]
default:"[408, 409, 425, 429, 500, 502, 503, 504]"
Array of HTTP status codes that should trigger a retry.

Retry with Rate Limiting

Handle rate limiting with exponential backoff:

Abort Signal and Retries

Abort signals prevent retries from happening:
When a request is aborted (via AbortController or timeout), ofetch will not retry the request, even if retry is configured.

Retry Logic Flow

  1. Request is made
  2. If request fails or returns a retryable status code:
    • Check if retry count is greater than 0
    • Check if status code is in retryStatusCodes (or default list)
    • Check if request was not aborted
  3. If all checks pass:
    • Wait for retryDelay milliseconds
    • Retry the request with retry count decremented by 1
  4. If retry count reaches 0, throw FetchError

Complete Example