HTTP

502 - Bad Gateway

Getting a 502 Bad Gateway means the gateway or proxy server received an invalid response from the upstream server—the backend crashed, returned malformed data, or closed the connection unexpectedly. This server-side error (5xx) happens when infrastructure (load balancer, reverse proxy, API gateway) can't get a valid response from the application server. Most common when the backend application crashes or times out, but also appears when upstream servers return invalid HTTP responses, network issues break connections mid-request, or the backend is overloaded and can't respond.

#Common Causes

  • Frontend: Client can't fix 502s directly, but retries can help if it's transient. No retry logic means users see errors during backend restarts.
  • Backend: Application server crashed or is restarting. Backend returns invalid HTTP response (malformed headers, incomplete response). Backend times out before completing request. Application errors cause backend to close connection. Database connection failures cascade to HTTP errors.
  • Infrastructure: Upstream server is down or unreachable. Network issues between gateway and backend (timeouts, packet loss). Load balancer health checks fail. Reverse proxy misconfiguration. API gateway can't reach backend service.

Solutions

  1. 1Step 1: Diagnose - Check gateway/proxy logs (Nginx error.log, load balancer logs) for upstream connection errors. Look for "upstream timed out", "connection refused", or "invalid response" messages. Check if backend server is running.
  2. 2Step 2: Diagnose - Check backend application logs for crashes or errors. Verify backend server status (systemctl status, process list). Check network connectivity between gateway and backend. Review health check endpoints.
  3. 3Step 3: Fix - Client-side: Implement retry logic with exponential backoff for 502s (they're often transient). Show user-friendly error messages. Log 502 errors for monitoring. Implement circuit breakers.
  4. 4Step 4: Fix - Server-side: Restart crashed backend application. Fix application errors causing invalid responses. Increase backend timeout settings. Add health check endpoints. Implement graceful shutdown.
  5. 5Step 5: Fix - Infrastructure: Increase gateway timeout settings (proxy_read_timeout, proxy_connect_timeout). Configure health checks properly. Add fallback upstream servers. Fix network connectivity issues. Scale backend if overloaded.

</>Code Examples

Fetch API: Retry Logic for 502 Errors
1// Client-side: Handle 502 with retry (often transient)
2async function fetchWithGatewayRetry(url, options = {}, maxRetries = 3) {
3  for (let attempt = 0; attempt < maxRetries; attempt++) {
4    try {
5      const response = await fetch(url, options);
6      
7      if (response.status === 502) {
8        if (attempt < maxRetries - 1) {
9          // Exponential backoff for gateway errors
10          const delay = Math.pow(2, attempt) * 1000;
11          console.warn(`Gateway error, retrying in ${delay}ms (attempt ${attempt + 1})`);
12          await new Promise(resolve => setTimeout(resolve, delay));
13          continue;
14        } else {
15          throw new Error('Gateway error after maximum retries');
16        }
17      }
18      
19      return response;
20    } catch (error) {
21      if (attempt === maxRetries - 1) {
22        throw error;
23      }
24      // Network errors - retry with backoff
25      const delay = Math.pow(2, attempt) * 1000;
26      await new Promise(resolve => setTimeout(resolve, delay));
27    }
28  }
29}
30
31// Usage with user feedback
32async function loadData() {
33  try {
34    const response = await fetchWithGatewayRetry('/api/data');
35    return await response.json();
36  } catch (error) {
37    showUserMessage({
38      type: 'error',
39      title: 'Service Temporarily Unavailable',
40      message: 'The server is temporarily unavailable. Please try again in a moment.',
41    });
42    throw error;
43  }
44}
Express.js: Gateway Error Handling
1// Server-side: Handle upstream errors gracefully
2const express = require('express');
3const app = express();
4
5// Gateway/proxy middleware
6app.use('/api', async (req, res, next) => {
7  try {
8    const upstreamUrl = process.env.UPSTREAM_URL || 'http://backend:3000';
9    const timeout = 30000; // 30 seconds
10    
11    // Create AbortController for timeout
12    const controller = new AbortController();
13    const timeoutId = setTimeout(() => controller.abort(), timeout);
14    
15    const upstreamResponse = await fetch(upstreamUrl + req.path, {
16      method: req.method,
17      headers: {
18        ...req.headers,
19        'host': new URL(upstreamUrl).host,
20      },
21      body: req.method !== 'GET' && req.method !== 'HEAD' 
22        ? JSON.stringify(req.body) 
23        : undefined,
24      signal: controller.signal,
25    });
26    
27    clearTimeout(timeoutId);
28    
29    // Check for invalid response
30    if (!upstreamResponse.ok && upstreamResponse.status >= 500) {
31      return res.status(502).json({
32        error: 'Bad Gateway',
33        message: 'Upstream server returned an error',
34      });
35    }
36    
37    // Forward response
38    const data = await upstreamResponse.json();
39    res.status(upstreamResponse.status).json(data);
40  } catch (error) {
41    if (error.name === 'AbortError') {
42      return res.status(504).json({ error: 'Gateway Timeout' });
43    }
44    
45    console.error('Gateway error:', error);
46    res.status(502).json({
47      error: 'Bad Gateway',
48      message: 'Failed to connect to upstream server',
49    });
50  }
51});
52
53// Health check endpoint (bypasses gateway)
54app.get('/health', (req, res) => {
55  res.json({ status: 'ok', timestamp: new Date().toISOString() });
56});
Nginx: Gateway Error Handling
1# Nginx: Configure gateway with proper error handling
2upstream backend {
3    server backend1:3000 max_fails=3 fail_timeout=30s;
4    server backend2:3000 max_fails=3 fail_timeout=30s backup;
5    keepalive 32;
6}
7
8server {
9    listen 80;
10    server_name api.example.com;
11    
12    location /api/ {
13        proxy_pass http://backend;
14        proxy_set_header Host $host;
15        proxy_set_header X-Real-IP $remote_addr;
16        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
17        
18        # Timeouts
19        proxy_connect_timeout 10s;
20        proxy_send_timeout 30s;
21        proxy_read_timeout 30s;
22        
23        # Error handling
24        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
25        proxy_next_upstream_tries 3;
26        proxy_next_upstream_timeout 10s;
27        
28        # Custom 502 error page
29        error_page 502 503 504 /50x.html;
30    }
31    
32    # Health check (bypasses error handling)
33    location /health {
34        proxy_pass http://backend/health;
35        access_log off;
36    }
37    
38    # Custom error page
39    location = /50x.html {
40        root /usr/share/nginx/html;
41        internal;
42    }
43}

Related Errors

Provider Information

This error code is specific to HTTP services. For more information, refer to the official HTTP documentation.

502 - Bad Gateway | HTTP Error Reference | Error Code Reference