spyderproxy

HTTP 503 Service Unavailable: Causes & Complete Fix Guide

D

Daniel K.

|
Published date

Sun May 10 2026

Quick verdict: HTTP 503 Service Unavailable is a temporary failure — the server got your request, but cannot respond right now. Five common causes: (1) the server is overloaded, (2) it is in maintenance mode, (3) you are being rate-limited, (4) Cloudflare/anti-bot is blocking, or (5) an upstream service the server depends on is down. The right response: respect any Retry-After header, back off exponentially, and retry. Unlike 404, 503 means "try again later" — it WILL work eventually.

What 503 Actually Means

From RFC 7231 §6.6.4: "The 503 status code indicates that the server is currently unable to handle the request due to a temporary overload or scheduled maintenance, which will likely be alleviated after some delay."

Key word: temporary. 503 differs from:

  • 500 Internal Server Error — the server crashed on YOUR request specifically (a bug in their code). Retry might work, but the problem is in the request handler.
  • 502 Bad Gateway — the front-end server got an invalid response from the back-end. Often resolves on retry.
  • 504 Gateway Timeout — the back-end took too long to respond. Server might be slow, not broken.
  • 521 Web Server Is Down (Cloudflare-specific) — the origin server is unreachable from Cloudflare's edge.

The 5 Common Causes

1. Server Overload

The server is processing requests but its queue is full. Common after viral traffic, news mentions, or flash sales. Symptoms:

  • Returns 503 randomly — some requests succeed, some fail
  • Slow response time even on success
  • Often paired with Retry-After header suggesting 30-300 seconds

2. Maintenance Mode

The server is deliberately offline for upgrades. Usually:

  • Returns 503 consistently (every request fails)
  • HTML body has a maintenance message
  • Retry-After header set to a specific timestamp or duration

3. Rate Limiting (often Cloudflare)

You exceeded the per-IP request budget. Cloudflare and many WAFs return 503 (or 429) when you hit limits:

  • Specific to your IP (a different IP works)
  • Body may say "Rate limited" or show a Cloudflare error page (often error 1015 or 1020)
  • Slows down if you wait, resolves fully after window expires (60s typical)

4. Cloudflare Protection (Bot Fight Mode)

Cloudflare's anti-bot decided your request looks automated. Returns 503 with a specific error number:

  • Error 1020: Access denied by firewall rule. Your IP is blocklisted.
  • Error 1015: You are being rate-limited.
  • Error 1006/1007/1008: Banned by IP / range.

See Cloudflare error codes explained for the full list.

5. Upstream Failure

The server depends on another service (database, microservice, third-party API) that is down. Less common with monoliths, very common in microservice architectures. Symptoms: returns 503 even on simple endpoints; sometimes paired with 502/504 on others.

The Retry-After Header

503 responses often include a Retry-After header telling you when to retry:

HTTP/1.1 503 Service Unavailable
Retry-After: 120
Content-Type: text/html

<html>...maintenance message...</html>

Two formats:

  • Seconds: Retry-After: 120 (wait 120 seconds)
  • HTTP date: Retry-After: Mon, 15 Sep 2026 12:00:00 GMT (wait until that time)

Always respect Retry-After. Ignoring it gets your IP escalated to a hard ban faster than anything else.

How Scrapers Should Handle 503

The standard pattern with Python requests retry:

from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
import requests

session = requests.Session()
retry = Retry(
    total=5,
    backoff_factor=2,                      # 2, 4, 8, 16, 32s
    status_forcelist=[429, 500, 502, 503, 504],
    respect_retry_after_header=True,       # honor Retry-After
)
session.mount("https://", HTTPAdapter(max_retries=retry))
session.mount("http://", HTTPAdapter(max_retries=retry))

r = session.get("https://example.com/api/data", timeout=10)

If you keep getting 503s after several retries, the cause is probably IP-level rate limiting or Cloudflare protection — switch IPs.

Rotate Proxies on Repeated 503

import requests, random

def fetch_with_rotation(url, max_attempts=5):
    for attempt in range(max_attempts):
        session_id = random.randint(0, 100000)
        proxy = f"http://USER-session-{session_id}:[email protected]:8000"
        try:
            r = requests.get(url, proxies={"http": proxy, "https": proxy}, timeout=15)
            if r.status_code == 200:
                return r
            if r.status_code == 503:
                print(f"  attempt {attempt+1}: 503, rotating IP")
                continue
        except requests.RequestException:
            continue
    raise RuntimeError("All attempts returned 503")

Each retry uses a fresh sticky-session IP via the session-{id} token in the proxy username. If the 503 is rate-limit-based, the new IP succeeds. Use Premium Residential ($2.75/GB) for clean IP pools.

Diagnosing 503 vs Other Causes

  1. Check the HTML body — maintenance pages, Cloudflare error pages, and overload messages look different.
  2. Try a different IP — if it works, you were rate-limited or IP-banned.
  3. Try at a different time — if it works in a few hours, it was overload or maintenance.
  4. Check the cf-mitigated header — if present, it is a Cloudflare block.
  5. Test from a fresh browser — if a real browser works but your scraper does not, it is an anti-bot issue.

If You Run the Server: Fixing 503

From the server side, 503 means your infrastructure cannot keep up:

  • Scale horizontally — add more app servers behind the load balancer.
  • Increase pool sizes — database connection pool, worker threads, queue capacity.
  • Add a CDN cache — offload static and cacheable dynamic responses to the edge.
  • Send Retry-After — tells clients exactly when to retry, prevents thundering-herd.
  • Auto-scaling rules — trigger scale-out on CPU/queue depth before 503 starts.

Related Status Codes

CodeNameMeaning
429Too Many RequestsRate-limited explicitly (see HTTP 429 guide)
500Internal Server ErrorBug in the server's code on this request
502Bad GatewayUpstream returned invalid response
503Service UnavailableTemporarily unable to handle
504Gateway TimeoutUpstream did not respond in time
521Web Server Is Down (CF)Origin unreachable from CDN

Related: HTTP 429 Too Many Requests, HTTP 403 Forbidden, Cloudflare error codes, Python requests retry.