How to Configure Nginx to Always Return HTTP 503 for All Requests


2 views

When implementing HAProxy with multiple backend servers, you might need a fallback server that consistently returns HTTP 503 (Service Unavailable) status. This is particularly useful when all backend servers are down, and you want to explicitly signal unavailability rather than serving stale content or connection errors.

The simplest way to force 503 responses is to configure a server block that returns this status for all requests:


server {
    listen 80;
    server_name fallback.example.com;
    
    location / {
        return 503;
    }
    
    error_page 503 /503.html;
    location = /503.html {
        internal;
        root /usr/share/nginx/html;
    }
}

For better user experience, you might want to serve a custom error page while maintaining the 503 status:


server {
    listen 80 default_server;
    
    location / {
        return 503;
        # Optional: add maintenance message
        add_header Retry-After 3600;
    }
    
    error_page 503 /maintenance.html;
    location = /maintenance.html {
        root /var/www/html;
        internal;
    }
}

To ensure all HTTP methods (GET, POST, etc.) receive 503 responses:


server {
    listen 80;
    
    location / {
        if ($request_method) {
            return 503;
        }
    }
}

When using this as a fallback server in HAProxy, consider these optimizations:


server {
    listen 80 reuseport;
    server_name _;
    
    access_log off;
    error_log /dev/null crit;
    
    location / {
        return 503;
    }
}

After implementing, verify with curl:


curl -I http://your-nginx-server
HTTP/1.1 503 Service Unavailable
Server: nginx/1.18.0
Content-Type: text/html
Connection: keep-alive

In your HAProxy configuration, reference this Nginx instance as a backup:


backend app_cluster
    balance roundrobin
    server app1 10.0.0.1:80 check
    server app2 10.0.0.2:80 check
    server fallback 10.0.0.3:80 backup

When building high-availability systems with HAProxy, you sometimes need a designated "backup" server that intentionally returns 503 (Service Unavailable) responses. This becomes particularly useful when:

  • All backend servers are down
  • You want to prevent HAProxy from marking the backup server as available
  • You need a maintenance mode endpoint

Create a dedicated server block that returns 503 for all requests:

server {
    listen 80;
    server_name backup.example.com;
    
    location / {
        return 503;
    }
    
    error_page 503 /503.html;
    location = /503.html {
        internal;
        root /usr/share/nginx/html;
    }
}

For more control over the behavior:

server {
    listen 80 default_server;
    server_name _;
    
    # Return 503 for all requests
    location / {
        return 503;
        add_header Retry-After 3600;
    }
    
    # Custom error page handling
    error_page 503 @maintenance;
    location @maintenance {
        internal;
        add_header Content-Type text/html;
        return 503 "<html><body><h1>Service Unavailable</h1></body></html>";
    }
    
    # Prevent logging these requests
    access_log off;
}

In your HAProxy configuration, reference this Nginx instance as a backup:

backend app_cluster
    balance roundrobin
    option httpchk GET /health
    server app1 192.168.1.10:80 check
    server app2 192.168.1.11:80 check
    server backup 192.168.1.12:80 check backup

Verify your setup works correctly:

curl -v http://backup.example.com
# Should return:
# HTTP/1.1 503 Service Unavailable
# Server: nginx/1.18.0
# ...

Since this Nginx instance won't process any real requests, you can optimize it:

  • Disable access logging completely
  • Set worker_processes to 1
  • Reduce worker_connections to minimal value