Nginx: How to Not Exit if "Host Not Found in Upstream"?

Better Stack Team
Updated on October 7, 2024

In Nginx, if you're using an upstream block and a specified server is not found or is down, Nginx will typically return an error to the client. By default, if Nginx cannot connect to any of the upstream servers, it will respond with a 502 Bad Gateway or 504 Gateway Timeout error, depending on the exact circumstances.

If you want to ensure that Nginx does not exit or fail entirely when a specific upstream server is not found, and instead handle such situations gracefully, you need to use various configurations to manage error handling and failover.

1. Configuring Upstream with Multiple Servers

Define multiple upstream servers to ensure that if one server is down or not found, Nginx can still attempt to connect to the other servers.

Example:

 
upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
}

In this setup, if backend1.example.com is not reachable, Nginx will try the other servers (backend2.example.com and backend3.example.com).

2. Error Handling with proxy_intercept_errors

You can use the proxy_intercept_errors directive to handle errors returned by upstream servers and serve custom error pages or alternative responses.

Example:

 
server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass <http://backend>;
        proxy_intercept_errors on;
        error_page 502 503 504 /custom_50x.html;
    }

    location = /custom_50x.html {
        internal;
        root /usr/share/nginx/html;
    }
}

In this configuration:

  • proxy_intercept_errors on; allows Nginx to handle errors from the upstream servers and serve a custom error page (/custom_50x.html).

3. Using fallback with try_files

You can use try_files in combination with an internal redirect to provide fallback content if the upstream server is not available.

Example:

 
server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass <http://backend>;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Handle upstream errors
        error_page 502 =503 @fallback;
    }

    location @fallback {
        root /usr/share/nginx/html;
        internal;
        try_files /fallback.html =404;
    }
}

In this configuration:

  • If an upstream error occurs (e.g., 502 Bad Gateway), Nginx serves a fallback page located at /usr/share/nginx/html/fallback.html.

4. Configuring max_fails and fail_timeout

To control how Nginx handles failed attempts to connect to upstream servers, use the max_fails and fail_timeout directives within the upstream block.

Example:

 
upstream backend {
    server backend1.example.com max_fails=3 fail_timeout=30s;
    server backend2.example.com max_fails=3 fail_timeout=30s;
}

In this configuration:

  • max_fails=3 specifies that if an upstream server fails to respond 3 times, it will be considered unavailable.
  • fail_timeout=30s defines the time period during which the failures are counted.

5. Use backup Servers

You can designate certain servers as backup servers, which will only be used if all primary servers are unavailable.

Example:

 
upstream backend {
    server backend1.example.com;
    server backend2.example.com backup;
}

In this configuration:

  • backend2.example.com is a backup server and will only be used if backend1.example.com is not available.

6. Graceful Degradation

You can use a combination of these configurations to ensure your application can degrade gracefully even when some upstream servers fail. For instance, serving static content or a simplified version of your application while the primary upstream servers are unavailable.

Example:

 
server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass <http://backend>;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        error_page 502 =503 @fallback;
    }

    location @fallback {
        root /usr/share/nginx/html;
        internal;
        try_files /fallback.html /index.html =404;
    }
}

Summary

To handle scenarios where an upstream server might not be available and ensure Nginx does not fail completely:

  1. Define Multiple Upstream Servers: Ensure there are multiple upstream servers to handle failover.
  2. Use proxy_intercept_errors: Serve custom error pages or responses when upstream errors occur.
  3. Implement Fallback Handling: Use try_files and internal redirects to serve alternative content if upstream servers fail.
  4. Configure max_fails and fail_timeout: Control how Nginx handles failed server attempts.
  5. Designate Backup Servers: Use backup servers to handle requests when primary servers fail.

By implementing these strategies, you can ensure more resilient and fault-tolerant handling of upstream server issues in your Nginx setup.

Got an article suggestion? Let us know
Licensed under CC-BY-NC-SA

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Make your mark

Join the writer's program

Are you a developer and love writing and sharing your knowledge with the world? Join our guest writing program and get paid for writing amazing technical guides. We'll get them to the right readers that will appreciate them.

Write for us
Writer of the month
Marin Bezhanov
Marin is a software engineer and architect with a broad range of experience working...
Build on top of Better Stack

Write a script, app or project on top of Better Stack and share it with the world. Make a public repository and share it with us at our email.

community@betterstack.com

or submit a pull request and help us build better products for everyone.

See the full list of amazing projects on github