Skip to content
← All articles

HTTP 503 Service Unavailable: Causes and Solutions

503 Service Unavailable is the server saying "I am alive but cannot serve this request right now." Unlike 500, this is NOT an exception: the cause is known to the server and usually temporary. Let us cover the real scenarios that cause 503, how to use it correctly as a maintenance tool, and how to restore service quickly.

What 503 Means

Per RFC 9110 §15.6.4, 503 means the server is temporarily unable to handle the request due to overload or scheduled maintenance. It is a temporary state — the client should retry later.

Important: 503 MUST include a Retry-After header telling clients how many seconds to wait. This is critical for search bots — Googlebot handles 503 with Retry-After gracefully and does not deindex the site.

6 Common Causes of 503

  1. Server overload — CPU/RAM exhausted, workers saturated.
  2. Maintenance mode — admin took the site down for updates.
  3. PHP-FPM pool exhausted — all children busy, new requests queued.
  4. Rate limiting — nginx limit_req or Cloudflare throttled traffic.
  5. Kubernetes healthcheck fail — pod not ready, readinessProbe failed.
  6. Upstream overload behind load balancer — all backends reporting unhealthy.

How 503 Differs from 500 and 502

CodeWhat HappenedRoot Cause
500Exception in application codeApplication
502Proxy got no valid response from upstreamUpstream unreachable
503Server temporarily unavailable (known reason)Overload / maintenance
504Upstream response timeoutSlow upstream

Diagnosis

Check externally via the HTTP Header Checker by Enterno.io — you will see the status code and the Retry-After header. If it is missing, the server is not configured correctly.

curl -I https://example.com
# HTTP/2 503
# Retry-After: 120
# Content-Type: text/html

# Server: check load
top -bn1 | head -20
free -m
ss -s

# PHP-FPM status
systemctl status php8.4-fpm
curl http://127.0.0.1/fpm-status

Solutions

nginx: proper 503 for maintenance

server {
    # Maintenance toggle
    if (-f /var/www/maintenance.flag) {
        return 503;
    }

    error_page 503 @maintenance;
    location @maintenance {
        root /var/www/maintenance;
        rewrite ^(.*)$ /503.html break;
        add_header Retry-After 300 always;
    }
}

PHP: 503 during deployment

<?php
if (file_exists(__DIR__ . '/maintenance.flag')) {
    header('HTTP/1.1 503 Service Unavailable');
    header('Retry-After: 300');
    header('Content-Type: text/html; charset=utf-8');
    readfile(__DIR__ . '/503.html');
    exit;
}

PHP-FPM: increase worker pool

# /etc/php/8.4/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500

Calculate max_children as (RAM_MB - 500) / 30, where 30MB is the average PHP worker size.

Rate limiting without 503 chaos

limit_req_zone $binary_remote_addr zone=api:10m rate=60r/m;

location /api/ {
    limit_req zone=api burst=20 nodelay;
    limit_req_status 429;  # prefer 429 over 503 for rate limits
    proxy_pass http://backend;
}

For rate limiting, use 429 Too Many Requests, not 503.

Kubernetes readinessProbe

readinessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5
  failureThreshold: 3

SEO-safe Maintenance

Correct maintenance mode:

After maintenance, verify the site via Uptime Monitoring — configure an alert for any deviation from 200.

Frequently Asked Questions

Q: Is 503 during deployment OK?
A: Yes, if brief (<30 sec) and with Retry-After. For zero-downtime deploys use blue-green or rolling deployment.

Q: Will Google deindex my site because of 503?
A: No — if 503 lasts up to 24-48 hours. For prolonged 503 (>1 week) deindexing starts.

Q: How can I be notified of 503 automatically?
A: Enterno.io Monitors with expected_code=200 sends Email/Telegram/Slack alerts within seconds.

Q: Is Retry-After required?
A: Yes. Without it, clients and bots retry aggressively, worsening the overload.

Conclusion

503 is a tool, not a bug, when used correctly. Keys: always return Retry-After, size your PHP-FPM pool to real traffic, use 429 for rate limits, and monitor your site via Enterno.io.

Check your website right now

Check now →
More articles: HTTP
HTTP
HTTP 403 Forbidden Error: 8 Ways to Fix
15.04.2026 · 8 views
HTTP
HTTP Headers: The Complete Guide
10.03.2025 · 51 views
HTTP
HTTP Cache-Control Headers: Complete Caching Guide
15.04.2026 · 8 views
HTTP
HTTP 504 Gateway Timeout: Causes and Solutions for Sysadmins
15.04.2026 · 7 views