Configuring nginx to retry a single upstream server

Solution 1:

The directives you tried are meant for different things than what you wish. Read their documentation.

The upstream directive documentation explains thoroughly how an upstream block works:

If an error occurs during communication with a server, the request will be passed to the next server, and so on until all of the functioning servers will be tried. If a successful response could not be obtained from any of the servers, the client will receive the result of the communication with the last server.

Everything said there.

However you might be able to process the returned error code from backend by intercepting it with proxy_intercept_errors and then send the $request_uri to a special script dealing with it on the behalf of the original client.

The baseline is: you need some code/application logic to retry client-side (or frontend-side).

Solution 2:

As stated in another answer, there is no built-in way to make nginx do this. A possible solution is to use a load-balancing setup consisting of your current server, and a backup server that does the following for all requests:

  • poll your current server until it's back online
  • then respond with a 302 or other redirect so the browser tries again

This server would be marked with the 'backup' flag so that it's only tried when all other servers are offline (HTTP Load Balancing > Server Weights).