From a3bb6d6d12d70422fa81008c057f5f23ab875530 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 22 Jan 2026 18:44:01 +0000
Subject: [PATCH 1/4] Initial plan
From 3579378300293f35923d57a12c102019eb82ac89 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 22 Jan 2026 18:49:51 +0000
Subject: [PATCH 2/4] Add NGINX configuration examples with proper error
handling
- Separate maintenance mode (503) from other errors
- Add distinct error pages for 502, 504, 500, 429
- Include maintenance flag file approach
- Add comprehensive documentation
Co-authored-by: JacobZwang <59858341+JacobZwang@users.noreply.github.com>
---
examples/nginx/README.md | 182 ++++++++++++++++++++
examples/nginx/error-pages/429.html | 57 ++++++
examples/nginx/error-pages/500.html | 76 ++++++++
examples/nginx/error-pages/502.html | 76 ++++++++
examples/nginx/error-pages/504.html | 76 ++++++++
examples/nginx/error-pages/maintenance.html | 57 ++++++
examples/nginx/nginx.conf | 100 +++++++++++
7 files changed, 624 insertions(+)
create mode 100644 examples/nginx/README.md
create mode 100644 examples/nginx/error-pages/429.html
create mode 100644 examples/nginx/error-pages/500.html
create mode 100644 examples/nginx/error-pages/502.html
create mode 100644 examples/nginx/error-pages/504.html
create mode 100644 examples/nginx/error-pages/maintenance.html
create mode 100644 examples/nginx/nginx.conf
diff --git a/examples/nginx/README.md b/examples/nginx/README.md
new file mode 100644
index 0000000..5ef3c15
--- /dev/null
+++ b/examples/nginx/README.md
@@ -0,0 +1,182 @@
+# NGINX Configuration Examples for Error Handling
+
+This directory contains example NGINX configuration files that demonstrate proper error handling patterns, specifically addressing the issue where HTTP 503 was being used for both maintenance mode and other server errors.
+
+## Problem Statement
+
+Previously, the maintenance page was being served for many different errors because HTTP 503 (Service Unavailable) was being used to indicate maintenance mode, but 503 was also being generated for other reasons like backend failures, timeouts, and other issues.
+
+## Solution
+
+This configuration separates maintenance mode from other error conditions:
+
+### Error Code Usage
+
+- **503 (Service Unavailable)**: Reserved ONLY for scheduled maintenance mode
+ - Triggered by the presence of `/var/www/maintenance.flag` file
+ - Displays `maintenance.html`
+
+- **502 (Bad Gateway)**: Backend server is down or unreachable
+ - Occurs when upstream server cannot be reached
+ - Displays `502.html`
+
+- **504 (Gateway Timeout)**: Backend server timeout
+ - Occurs when upstream server takes too long to respond
+ - Displays `504.html`
+
+- **500 (Internal Server Error)**: Application errors
+ - Occurs when the application encounters an error
+ - Displays `500.html`
+
+- **429 (Too Many Requests)**: Rate limiting
+ - Occurs when rate limits are exceeded
+ - Displays `429.html`
+
+## Files
+
+```
+examples/nginx/
+├── nginx.conf # Main NGINX configuration
+├── error-pages/
+│ ├── maintenance.html # Scheduled maintenance page (503)
+│ ├── 502.html # Bad Gateway error page
+│ ├── 504.html # Gateway Timeout error page
+│ ├── 500.html # Internal Server Error page
+│ └── 429.html # Too Many Requests page
+└── README.md # This file
+```
+
+## Usage
+
+### Basic Setup
+
+1. Copy the `nginx.conf` to your NGINX configuration directory:
+ ```bash
+ sudo cp nginx.conf /etc/nginx/sites-available/your-site
+ sudo ln -s /etc/nginx/sites-available/your-site /etc/nginx/sites-enabled/
+ ```
+
+2. Copy the error pages to your web root:
+ ```bash
+ sudo cp -r error-pages/* /var/www/html/
+ ```
+
+3. Test and reload NGINX:
+ ```bash
+ sudo nginx -t
+ sudo systemctl reload nginx
+ ```
+
+### Enabling Maintenance Mode
+
+To enable maintenance mode, simply create the maintenance flag file:
+
+```bash
+sudo touch /var/www/maintenance.flag
+```
+
+To disable maintenance mode, remove the flag file:
+
+```bash
+sudo rm /var/www/maintenance.flag
+```
+
+### Customization
+
+#### Change Maintenance Flag Location
+
+Edit the `nginx.conf` file and update the path in the `if` statement:
+
+```nginx
+if (-f /your/custom/path/maintenance.flag) {
+ return 503;
+}
+```
+
+#### Customize Error Pages
+
+All error pages are standard HTML files. You can edit them to match your branding:
+
+```bash
+sudo nano /var/www/html/maintenance.html
+```
+
+#### Add Backend Servers
+
+Update the `upstream backend` block in `nginx.conf`:
+
+```nginx
+upstream backend {
+ server backend1.example.com:8080 max_fails=3 fail_timeout=30s;
+ server backend2.example.com:8080 max_fails=3 fail_timeout=30s;
+ keepalive 32;
+}
+```
+
+## Testing
+
+### Test Maintenance Mode
+
+```bash
+# Enable maintenance
+sudo touch /var/www/maintenance.flag
+curl -I http://localhost
+# Should return HTTP 503 with maintenance page
+
+# Disable maintenance
+sudo rm /var/www/maintenance.flag
+curl -I http://localhost
+# Should return normal response
+```
+
+### Test Other Error Pages
+
+You can test other error pages by temporarily configuring NGINX to return specific status codes:
+
+```nginx
+location /test-502 {
+ return 502;
+}
+
+location /test-504 {
+ return 504;
+}
+```
+
+## Integration with Tracing-Stackdriver
+
+When using this NGINX configuration with applications that use the `tracing-stackdriver` library, error responses will be properly logged with their correct HTTP status codes, making it easier to distinguish between:
+
+- Scheduled maintenance (503)
+- Infrastructure issues (502, 504)
+- Application errors (500)
+- Rate limiting (429)
+
+This improves observability and helps with debugging and monitoring in Google Cloud Operations Suite.
+
+## Best Practices
+
+1. **Always use the maintenance flag file**: Never return 503 directly for other error conditions
+2. **Monitor upstream health**: Configure proper health checks in your upstream blocks
+3. **Set appropriate timeouts**: Adjust `proxy_*_timeout` values based on your application's needs
+4. **Log errors appropriately**: Ensure error logs are being sent to your monitoring system
+5. **Test maintenance mode regularly**: Verify that maintenance mode works as expected before you need it
+6. **Keep error pages simple**: Error pages should load quickly and have minimal dependencies
+7. **Provide helpful information**: Include relevant contact information or status page links
+
+## Troubleshooting
+
+### Maintenance page not showing
+- Check that `/var/www/maintenance.flag` exists
+- Verify NGINX configuration syntax: `sudo nginx -t`
+- Check NGINX error logs: `sudo tail -f /var/log/nginx/error.log`
+
+### Wrong error page displayed
+- Verify error page files exist in `/var/www/html/`
+- Check file permissions: `sudo chmod 644 /var/www/html/*.html`
+- Ensure `error_page` directives are not being overridden in other config files
+
+### Backend connection issues
+- Verify upstream server is running
+- Check firewall rules between NGINX and backend
+- Test direct connection: `curl http://backend-ip:port`
diff --git a/examples/nginx/error-pages/429.html b/examples/nginx/error-pages/429.html
new file mode 100644
index 0000000..edc70db
--- /dev/null
+++ b/examples/nginx/error-pages/429.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Too Many Requests
+
+
+
+
+
🚦
+
Too Many Requests
+
You've made too many requests in a short period.
+
Please wait a moment before trying again.
+
HTTP 429 - Too Many Requests
+
+
+
diff --git a/examples/nginx/error-pages/500.html b/examples/nginx/error-pages/500.html
new file mode 100644
index 0000000..2758540
--- /dev/null
+++ b/examples/nginx/error-pages/500.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+ Internal Server Error
+
+
+
+
+
⚠️
+
Internal Server Error
+
Something went wrong on our end.
+
We've been notified and are working to fix the issue.
+
+
+
+
HTTP 500 - Internal Server Error
+
+
+
diff --git a/examples/nginx/error-pages/502.html b/examples/nginx/error-pages/502.html
new file mode 100644
index 0000000..67a2e20
--- /dev/null
+++ b/examples/nginx/error-pages/502.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+ Bad Gateway
+
+
+
+
+
🔌
+
Bad Gateway
+
We're having trouble connecting to our servers.
+
Our team has been notified and is working to resolve the issue.
+
+
+
+
HTTP 502 - Bad Gateway
+
+
+
diff --git a/examples/nginx/error-pages/504.html b/examples/nginx/error-pages/504.html
new file mode 100644
index 0000000..cf9fd14
--- /dev/null
+++ b/examples/nginx/error-pages/504.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+ Gateway Timeout
+
+
+
+
+
⏱️
+
Gateway Timeout
+
The request took too long to process.
+
Our servers might be experiencing high load. Please try again in a moment.
+
+
+
+
HTTP 504 - Gateway Timeout
+
+
+
diff --git a/examples/nginx/error-pages/maintenance.html b/examples/nginx/error-pages/maintenance.html
new file mode 100644
index 0000000..cad92e6
--- /dev/null
+++ b/examples/nginx/error-pages/maintenance.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Scheduled Maintenance
+
+
+
+
+
🔧
+
Scheduled Maintenance
+
We're currently performing scheduled maintenance to improve our services.
+
We'll be back shortly. Thank you for your patience!
+
HTTP 503 - Service Temporarily Unavailable
+
+
+
diff --git a/examples/nginx/nginx.conf b/examples/nginx/nginx.conf
new file mode 100644
index 0000000..7749c03
--- /dev/null
+++ b/examples/nginx/nginx.conf
@@ -0,0 +1,100 @@
+# Example NGINX configuration for services using tracing-stackdriver
+# This configuration demonstrates proper error handling with distinct pages
+# for maintenance vs other server errors
+
+# Main server configuration
+server {
+ listen 80;
+ server_name _;
+
+ # Root directory for static files and error pages
+ root /var/www/html;
+
+ # Custom error pages for different scenarios
+ # Use 503 ONLY for actual maintenance mode
+ error_page 503 @maintenance;
+
+ # Bad Gateway - upstream server is down or unreachable
+ error_page 502 /502.html;
+
+ # Gateway Timeout - upstream server timed out
+ error_page 504 /504.html;
+
+ # Internal Server Error
+ error_page 500 /500.html;
+
+ # Too Many Requests
+ error_page 429 /429.html;
+
+ # Maintenance mode check
+ # Create /var/www/maintenance.flag file to enable maintenance mode
+ location / {
+ # Check if maintenance mode is enabled
+ if (-f /var/www/maintenance.flag) {
+ return 503;
+ }
+
+ # Normal proxy pass to application
+ 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;
+
+ # Timeout settings to generate 504 instead of 503
+ proxy_connect_timeout 60s;
+ proxy_send_timeout 60s;
+ proxy_read_timeout 60s;
+ }
+
+ # Maintenance page handler
+ location @maintenance {
+ internal;
+ root /var/www/html;
+ rewrite ^(.*)$ /maintenance.html break;
+ }
+
+ # Ensure error pages are accessible
+ location = /502.html {
+ internal;
+ }
+
+ location = /503.html {
+ internal;
+ }
+
+ location = /504.html {
+ internal;
+ }
+
+ location = /500.html {
+ internal;
+ }
+
+ location = /429.html {
+ internal;
+ }
+
+ location = /maintenance.html {
+ internal;
+ }
+
+ # Health check endpoint (always available, even during maintenance)
+ location /health {
+ access_log off;
+ return 200 "OK\n";
+ add_header Content-Type text/plain;
+ }
+}
+
+# Backend upstream configuration
+upstream backend {
+ # Application servers
+ server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
+
+ # Uncomment for multiple backends
+ # server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
+
+ # Use keepalive connections
+ keepalive 32;
+}
From 10313284d019bcbf88499dba2bb07aff27e508e1 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 22 Jan 2026 18:51:31 +0000
Subject: [PATCH 3/4] Add standalone config, test script, and improve
documentation
- Add nginx-standalone.conf for complete testing setup
- Create automated test script (test-config.sh)
- Update README with test instructions
- Clarify nginx.conf is a server block snippet
- All tests passing successfully
Co-authored-by: JacobZwang <59858341+JacobZwang@users.noreply.github.com>
---
examples/nginx/README.md | 34 ++++++-
examples/nginx/nginx-standalone.conf | 125 +++++++++++++++++++++++++
examples/nginx/nginx.conf | 3 +
examples/nginx/test-config.sh | 134 +++++++++++++++++++++++++++
4 files changed, 294 insertions(+), 2 deletions(-)
create mode 100644 examples/nginx/nginx-standalone.conf
create mode 100755 examples/nginx/test-config.sh
diff --git a/examples/nginx/README.md b/examples/nginx/README.md
index 5ef3c15..38781d7 100644
--- a/examples/nginx/README.md
+++ b/examples/nginx/README.md
@@ -36,7 +36,9 @@ This configuration separates maintenance mode from other error conditions:
```
examples/nginx/
-├── nginx.conf # Main NGINX configuration
+├── nginx.conf # Server block configuration (for inclusion)
+├── nginx-standalone.conf # Complete standalone configuration (for testing)
+├── test-config.sh # Test script to validate configuration
├── error-pages/
│ ├── maintenance.html # Scheduled maintenance page (503)
│ ├── 502.html # Bad Gateway error page
@@ -50,7 +52,9 @@ examples/nginx/
### Basic Setup
-1. Copy the `nginx.conf` to your NGINX configuration directory:
+**Option 1: Include in existing configuration (recommended)**
+
+1. Copy the `nginx.conf` snippet to your NGINX sites directory:
```bash
sudo cp nginx.conf /etc/nginx/sites-available/your-site
sudo ln -s /etc/nginx/sites-available/your-site /etc/nginx/sites-enabled/
@@ -67,6 +71,16 @@ examples/nginx/
sudo systemctl reload nginx
```
+**Option 2: Standalone configuration (for testing)**
+
+1. Use the `nginx-standalone.conf` for a complete configuration:
+ ```bash
+ sudo cp nginx-standalone.conf /etc/nginx/nginx.conf
+ sudo cp -r error-pages/* /var/www/html/
+ sudo nginx -t
+ sudo systemctl restart nginx
+ ```
+
### Enabling Maintenance Mode
To enable maintenance mode, simply create the maintenance flag file:
@@ -115,6 +129,22 @@ upstream backend {
## Testing
+### Automated Testing
+
+Run the provided test script to validate the configuration:
+
+```bash
+cd examples/nginx
+./test-config.sh
+```
+
+The test script validates:
+- NGINX configuration syntax
+- Presence of all error page files
+- HTML structure of error pages
+- Key configuration features
+- Uniqueness of error page content
+
### Test Maintenance Mode
```bash
diff --git a/examples/nginx/nginx-standalone.conf b/examples/nginx/nginx-standalone.conf
new file mode 100644
index 0000000..25a9a41
--- /dev/null
+++ b/examples/nginx/nginx-standalone.conf
@@ -0,0 +1,125 @@
+# Complete standalone NGINX configuration for testing
+# This can be used as /etc/nginx/nginx.conf for validation
+
+user nginx;
+worker_processes auto;
+error_log /var/log/nginx/error.log warn;
+pid /var/run/nginx.pid;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+ log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+ '$status $body_bytes_sent "$http_referer" '
+ '"$http_user_agent" "$http_x_forwarded_for"';
+
+ access_log /var/log/nginx/access.log main;
+
+ sendfile on;
+ tcp_nopush on;
+ tcp_nodelay on;
+ keepalive_timeout 65;
+ types_hash_max_size 2048;
+
+ # Backend upstream configuration
+ upstream backend {
+ # Application servers
+ server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
+
+ # Uncomment for multiple backends
+ # server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
+
+ # Use keepalive connections
+ keepalive 32;
+ }
+
+ # Main server configuration
+ server {
+ listen 80;
+ server_name _;
+
+ # Root directory for static files and error pages
+ root /var/www/html;
+
+ # Custom error pages for different scenarios
+ # Use 503 ONLY for actual maintenance mode
+ error_page 503 @maintenance;
+
+ # Bad Gateway - upstream server is down or unreachable
+ error_page 502 /502.html;
+
+ # Gateway Timeout - upstream server timed out
+ error_page 504 /504.html;
+
+ # Internal Server Error
+ error_page 500 /500.html;
+
+ # Too Many Requests
+ error_page 429 /429.html;
+
+ # Maintenance mode check
+ # Create /var/www/maintenance.flag file to enable maintenance mode
+ location / {
+ # Check if maintenance mode is enabled
+ if (-f /var/www/maintenance.flag) {
+ return 503;
+ }
+
+ # Normal proxy pass to application
+ 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;
+
+ # Timeout settings to generate 504 instead of 503
+ proxy_connect_timeout 60s;
+ proxy_send_timeout 60s;
+ proxy_read_timeout 60s;
+ }
+
+ # Maintenance page handler
+ location @maintenance {
+ internal;
+ root /var/www/html;
+ rewrite ^(.*)$ /maintenance.html break;
+ }
+
+ # Ensure error pages are accessible
+ location = /502.html {
+ internal;
+ }
+
+ location = /503.html {
+ internal;
+ }
+
+ location = /504.html {
+ internal;
+ }
+
+ location = /500.html {
+ internal;
+ }
+
+ location = /429.html {
+ internal;
+ }
+
+ location = /maintenance.html {
+ internal;
+ }
+
+ # Health check endpoint (always available, even during maintenance)
+ location /health {
+ access_log off;
+ return 200 "OK\n";
+ add_header Content-Type text/plain;
+ }
+ }
+}
diff --git a/examples/nginx/nginx.conf b/examples/nginx/nginx.conf
index 7749c03..2a7c8a9 100644
--- a/examples/nginx/nginx.conf
+++ b/examples/nginx/nginx.conf
@@ -1,6 +1,9 @@
# Example NGINX configuration for services using tracing-stackdriver
# This configuration demonstrates proper error handling with distinct pages
# for maintenance vs other server errors
+#
+# NOTE: This is a server block configuration snippet.
+# Include this within your main nginx.conf http block or in sites-available/
# Main server configuration
server {
diff --git a/examples/nginx/test-config.sh b/examples/nginx/test-config.sh
new file mode 100755
index 0000000..b8c62b1
--- /dev/null
+++ b/examples/nginx/test-config.sh
@@ -0,0 +1,134 @@
+#!/bin/bash
+# Test script for NGINX error page configuration
+# This script demonstrates how to test different error scenarios
+
+set -e
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+CONFIG_FILE="$SCRIPT_DIR/nginx-standalone.conf"
+
+echo "========================================="
+echo "NGINX Error Page Configuration Test"
+echo "========================================="
+echo ""
+
+# Check if running as root
+if [ "$EUID" -ne 0 ]; then
+ echo "Note: This script should be run with sudo for full functionality"
+ echo "Continuing with syntax validation only..."
+ echo ""
+fi
+
+# Test 1: Validate configuration syntax
+echo "Test 1: Validating NGINX configuration syntax..."
+if nginx -t -c "$CONFIG_FILE" 2>&1 | grep -q "syntax is ok"; then
+ echo "✓ Configuration syntax is valid"
+else
+ echo "✗ Configuration syntax validation failed"
+ nginx -t -c "$CONFIG_FILE"
+ exit 1
+fi
+echo ""
+
+# Test 2: Check if error page files exist
+echo "Test 2: Checking error page files..."
+ERROR_PAGES=(
+ "$SCRIPT_DIR/error-pages/maintenance.html"
+ "$SCRIPT_DIR/error-pages/502.html"
+ "$SCRIPT_DIR/error-pages/504.html"
+ "$SCRIPT_DIR/error-pages/500.html"
+ "$SCRIPT_DIR/error-pages/429.html"
+)
+
+for page in "${ERROR_PAGES[@]}"; do
+ if [ -f "$page" ]; then
+ echo "✓ Found $(basename "$page")"
+ else
+ echo "✗ Missing $(basename "$page")"
+ exit 1
+ fi
+done
+echo ""
+
+# Test 3: Validate HTML in error pages
+echo "Test 3: Validating HTML structure..."
+for page in "${ERROR_PAGES[@]}"; do
+ # Check if it's valid HTML5 (basic check)
+ if grep -q "" "$page" && grep -q "