HTTP error 503 Service Unavailable: what it means and how to fix it

HTTP 503 means the server is temporarily unable to handle your request, usually because of maintenance or overload. If you are a visitor, wait and try again later, because the problem is on the server side. If you run the site, check for a stopped IIS application pool or nginx rate limiting and a failing backend.

Applies to:Any HTTP server, proxy, load balancer or CDNIISnginx
On this page

What it means

A 503 is a server error in the 5xx family. It tells you the server exists and received your request, but cannot deal with it right now. The usual reasons are planned maintenance or too much load. The wording is deliberate: 503 describes a temporary condition, and the server may include a Retry-After header with an estimate of when it will be back.

The error is not tied to a browser or device. Any web server, proxy, load balancer or CDN can return it. Because the cause sits on the server side, what you can do depends on which side of the screen you are on. Visitors mostly wait. Site owners have real work to do, and the two products covered below are IIS and nginx.

Symptoms and causes

You are likely dealing with this problem if:

  • The browser shows "503 Service Unavailable" or "Service Temporarily Unavailable".
  • IIS shows "HTTP Error 503. The service is unavailable."
  • An API client receives status 503, possibly with a Retry-After header.
  • Search crawlers reduce how often they visit the site (Google lowers its crawl rate when it sees server errors).

The usual causes, most common first:

Planned maintenance
Traffic is deliberately sent to a 503 page while the site is being updated or worked on.
Overload
The server refuses requests when CPU, memory or connection-pool limits are reached.
IIS application pool stopped by Rapid-Fail Protection
When Rapid-Fail Protection is on (the default), IIS takes the applications in a pool out of service once the worker process has crashed the maximum number of times within the interval. The defaults are 5 crashes within 5 minutes. Typical reasons for the crashes are an application error at startup, a wrong .NET CLR version or pipeline mode for the app, or a pool identity without access to the site folder. A stopped pool stays stopped after an IIS reset (per a Microsoft Q&A answer).
IIS request queue limits
The pool's queueLength setting tells HTTP.sys how many requests to queue for the pool (default 1000). When it is exceeded, IIS rejects further requests with a 503. Separately, the appConcurrentRequestLimit setting in serverRuntime limits how many requests can be queued for an application (default 5000).
nginx rate or connection limiting
The nginx limit_req and limit_conn modules reject requests with status 503 by default (set by limit_req_status and limit_conn_status).
Per-client rate limiting using 503
MDN recommends 429 for limits applied to individual clients, so a 503 used for this purpose is a configuration choice that can mislead.

How to fix it

Work through these in order. They start with the quickest, safest checks and move to deeper repairs; stop as soon as the problem is gone.

1.Wait and reload (visitors)

Easy

The condition is temporary and sits on the server, so there is nothing on your device to repair.

  1. Wait a few minutes, then reload the page. If the response includes a Retry-After value, wait at least that long.
  2. Check the service's status page or official social account for a maintenance or outage notice, and try again later.

2.Start a stopped IIS application pool

Moderate

A stopped pool is a common IIS cause, and it stays stopped even after an IIS reset.

  1. Open Internet Information Services (IIS) Manager and select Application Pools. If your site's pool shows Stopped, start it.
  2. Or check and start it with PowerShell (replace DefaultAppPool with your pool name).
    PowerShellrun as administrator
    Import-Module WebAdministration
    Get-WebAppPoolState -Name DefaultAppPool
    Start-WebAppPool -Name DefaultAppPool

3.Find why the IIS pool keeps stopping or rejecting requests

Advanced

If the pool stops again, the underlying crash has to be found and fixed.

  1. In Event Viewer, review the Application and System logs around the time the pool stopped, and look for errors from the worker process or the Windows Process Activation Service.
  2. Fix what you find: repair the application error (a missing component or bad configuration) and make sure the site folder actually contains content.
  3. Check the pool's .NET CLR version and Managed pipeline mode in Application Pools, and make sure they match what the application needs.
  4. Give the pool identity IIS AppPool\<pool name> Read and Execute permission on the site folder.
  5. If requests are rejected under heavy load rather than after crashes, look at the pool's Queue Length (the HTTP.sys queue, default 1000) in the pool's Advanced Settings. For per-application limits, check appConcurrentRequestLimit in the serverRuntime configuration (default 5000). Raise a limit only if the server has capacity, otherwise you move the problem.

4.Temporarily disable Rapid-Fail Protection (IIS)

AdvancedChanges settings

This stops IIS from taking the pool out of service while you investigate, but it only hides the symptom.

Before you start: Use this as a short-term workaround only. Turn Rapid-Fail Protection back on once the crash cause is fixed.

  1. In IIS Manager, select the pool and choose Advanced Settings.
  2. Under Rapid-Fail Protection, set Enabled to False. Restore it to True after the real problem is fixed.

5.Diagnose nginx 503 responses

Advanced

Knowing whether nginx itself is rejecting requests or the backend is failing tells you which side to fix.

  1. Check your configuration for limit_req and limit_conn. Both return 503 unless you changed limit_req_status or limit_conn_status, so a 503 on busy pages can simply be your own limit.
  2. Add $upstream_addr and $upstream_status to a log_format. They record which backend servers were tried and what each returned. A rejection by a limit has no upstream response, which helps separate it from a backend failure.
  3. If legitimate bursts are being rejected, raise burst on the limit_req zone, or use nodelay or delay (the latter needs nginx 1.15.7 or newer).
  4. To return a different status for rejected requests, set limit_req_status (available since nginx 1.3.15).
    nginx.conf
    limit_req_status 429;
  5. If the backend is the problem, fix or restart it. In an upstream group, nginx treats a server as unavailable for fail_timeout (default 10 seconds) after max_fails failed attempts (default 1), so a flapping backend can drop out of rotation.

6.Serve 503 responses correctly (site owners)

Moderate

Handled well, a 503 is harmless to visitors and to search ranking.

  1. Use 503 only for genuinely temporary conditions.
  2. Send a Retry-After header with an estimated recovery time.
  3. Do not cache 503 responses, otherwise users keep seeing the error page after the fix.
  4. Show a friendly error page that includes a request ID so support can trace the failure.
  5. Keep outages short. Google lowers its crawl rate in proportion to server errors and eventually removes URLs that keep returning them, though already-indexed URLs are kept for a while first. Once the server returns 2xx again, the crawl rate recovers gradually.

Check that it worked

  • The page loads with status 200 instead of 503.
  • On IIS, the application pool shows Started and stays that way after a few requests.
  • On nginx, normal traffic no longer produces 503 responses in the access log.

If it still fails

  • If the site is not yours, you cannot fix it. Contact the site's support or check its status page.
  • If you run the site on a host or CDN, open a ticket with them and include the time of the error and any request ID shown on the page.
  • For IIS, collect the Application and System log entries from the time of the failure before asking for help.
  • For nginx, collect the relevant error log lines and the limit_req, limit_conn and upstream configuration.
  • This article does not cover cloud-specific 503s (Cloudflare, AWS load balancers, Kubernetes) or Apache mod_proxy. Use that vendor's documentation for those.

Questions

Is a 503 error my fault?

Normally not. It is a server-side status, so a visitor's browser, device or connection is rarely the cause.

How is 503 different from 502?

A 503 means the server is temporarily unable to handle requests. For the proxy-to-backend case, see Nginx 502 Bad Gateway.

Sources

  1. 503 Service Unavailable | MDN Web DocsOfficial · Mozilla (MDN Web Docs)
  2. HTTP network errors / crawlingOfficial · Google Search Central
  3. Failure Settings for an Application Pool <failure>Official · Microsoft Learn
  4. Adding Application Pools <add>Official · Microsoft Learn
  5. Server Runtime <serverRuntime>Official · Microsoft Learn
  6. Fixing IIS 503 (Q&A answer) · Microsoft Learn Q&A
  7. ngx_http_limit_req_moduleOfficial · nginx.org
  8. ngx_http_limit_conn_moduleOfficial · nginx.org
  9. ngx_http_upstream_moduleOfficial · nginx.org