Sửa lỗi Nginx "upstream sent too big header" 502 Bad Gateway

intermediate🌐 Networking2026-07-01| Nginx 1.x làm reverse proxy trên Linux (Ubuntu 20.04/22.04, CentOS 7/8, Debian 11/12), upstream: Node.js, Python (Django/Flask), Ruby on Rails, PHP-FPM

Error Message

502 Bad Gateway - [error] upstream sent too big header while reading response header from upstream
#nginx#networking#proxy#backend

Lỗi Gặp Phải

Lỗi đầy đủ từ /var/log/nginx/error.log:

2024/01/15 10:23:45 [error] 12345#0: *1 upstream sent too big header while reading response header from upstream,
client: 10.0.0.1, server: example.com,
request: "GET /api/dashboard HTTP/1.1",
upstream: "http://127.0.0.1:3000/api/dashboard",
host: "example.com"

Trình duyệt hiển thị trang trắng với lỗi 502 Bad Gateway. Backend của bạn đang chạy bình thường — chính Nginx là thứ đang bị nghẹt với các response header.

Nguyên Nhân

Nginx cấp phát một buffer cố định để đọc response header từ upstream. Mặc định là 4KB (hoặc 8KB trên một số bản build). Khi upstream gửi header lớn hơn buffer đó, Nginx sẽ huỷ response và sinh ra lỗi này.

4KB nghe có vẻ dư dả cho đến khi bạn chạy một luồng xác thực thực tế. Những nguyên nhân phổ biến:

  • Cookie session cồng kềnh — PHP session, Rails encrypted cookie, hoặc JWT token lưu trong cookie có thể dễ dàng chạm ngưỡng 4–8KB.
  • Nhiều header Set-Cookie — Luồng OAuth, xác thực đa domain và hệ thống feature flag chồng chất cookie rất nhanh.
  • Header framework dài dòng — Spring Boot và Django REST đôi khi thêm vào một số lượng đáng ngạc nhiên các custom response header.
  • CDN hoặc auth middleware chèn thêm header — Cloudflare, Keycloak hoặc các API gateway nội bộ có thể làm phình kích thước header trước khi response đến được Nginx.

Các directive Nginx liên quan có giá trị mặc định phù hợp từ năm 2005. Ứng dụng web hiện đại thường xuyên vượt qua chúng.

Cách Sửa

Cách 1: Tăng kích thước proxy buffer (cách phổ biến nhất)

Chỉnh sửa file cấu hình Nginx của site — thường là /etc/nginx/sites-available/your-site, hoặc block server tương ứng trong /etc/nginx/nginx.conf:

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;

        # Fix: increase header buffer sizes
        proxy_buffer_size          128k;
        proxy_buffers              4 256k;
        proxy_busy_buffers_size    256k;
    }
}

Chức năng của từng directive:

  • proxy_buffer_size — buffer cho phần đầu tiên của upstream response (dòng status + header). Đây là directive then chốt cho lỗi này.
  • proxy_buffers — số lượng × kích thước buffer cho toàn bộ response body.
  • proxy_busy_buffers_size — kích thước tối đa đang được flush tích cực đến client. Không được vượt quá tổng kích thước của proxy_buffers.

Cách 2: Áp dụng toàn cục trong block http

Có nhiều upstream service gặp cùng vấn đề? Đặt một lần trong block http bên trong /etc/nginx/nginx.conf:

http {
    proxy_buffer_size          128k;
    proxy_buffers              4 256k;
    proxy_busy_buffers_size    256k;

    include /etc/nginx/sites-enabled/*;
}

Các block per-location sẽ ghi đè cài đặt toàn cục này, nên những nơi đã có giá trị tường minh sẽ không bị ảnh hưởng.

Cách 3: Biến thể FastCGI (PHP-FPM)

Đang chạy PHP qua FastCGI? Tên directive sẽ khác:

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;

    fastcgi_buffer_size          128k;
    fastcgi_buffers              4 256k;
    fastcgi_busy_buffers_size    256k;
}

Áp dụng bản sửa lỗi

# Kiểm tra cú pháp config trước
nginx -t

# Reload không gây downtime
systemctl reload nginx

Xác Nhận Bản Sửa Lỗi

Theo dõi error log trong khi gọi đến endpoint đang bị lỗi:

# Xem error log theo thời gian thực
tail -f /var/log/nginx/error.log

# Gọi đến endpoint bị lỗi
curl -v https://example.com/api/dashboard 2>&1 | grep -E '< HTTP|< Set-Cookie|< X-'

Cookie phình to là nguyên nhân phổ biến nhất. Đo kích thước header thực tế bằng lệnh:

curl -sI https://example.com/api/dashboard | awk '{total += length($0)} END {print "Total header size: " total " bytes"}'

Bất kỳ giá trị nào gần hoặc vượt 4096 byte đều xác nhận nguyên nhân gốc rễ.

Tìm Hiểu Sâu Hơn: Header Lớn Đến Từ Đâu?

Tăng buffer là cách sửa nhanh hợp lệ. Nhưng hãy dành hai phút để tìm xem thứ gì đang thực sự làm phình header — đôi khi câu trả lời đúng là thu gọn payload cookie, chứ không phải cứ tăng buffer của Nginx mãi.

# Kiểm tra response header từ upstream trực tiếp (bỏ qua Nginx)
curl -sI http://127.0.0.1:3000/api/dashboard

# Đếm tổng số byte của tất cả header
curl -sI http://127.0.0.1:3000/api/dashboard | wc -c

Khi Set-Cookie là thủ phạm, vấn đề thường nằm ở session store của bạn. CookieStore mặc định của Rails serialize toàn bộ payload session vào cookie — đó là cách kinh điển khiến cookie chạm ngưỡng 4KB+. Chuyển sang Redis hoặc database-backed session store và cookie sẽ thu gọn lại thành một session ID nhỏ gọn.

Phòng Ngừa

  • Đặt buffer chủ động mỗi khi bạn cấu hình Nginx proxy mới, đặc biệt với các ứng dụng dùng OAuth hoặc JWT cookie. Đừng đợi người dùng gặp lỗi 502 mới xử lý.
  • Lưu session phía server — dùng Redis, Memcached hoặc database thay vì serialize payload vào cookie. Giữ cookie chỉ chứa session ID.
  • Kiểm tra header định kỳ — auth middleware và framework thêm header một cách âm thầm theo thời gian. Một lệnh curl -sI nhanh mỗi tháng có thể phát hiện vấn đề trước khi nó trở thành sự cố.
  • Giới hạn kích thước cookie trong ứng dụng — cookie vượt 4KB gần như luôn là logic session bị lỗi, không phải trường hợp sử dụng hợp lệ. Phát hiện nó ở tầng ứng dụng trước khi Nginx phải xử lý.

Mẹo Hay

Khi debug các vấn đề ở tầng network như thế này, tôi đôi khi dùng thêm IP Subnet Calculator của ToolCraft — rất tiện khi bạn cũng đang sắp xếp dải mạng nội bộ upstream hoặc xác minh các CIDR block trong proxy config. Chạy hoàn toàn trên trình duyệt, không upload dữ liệu.

Tham Khảo Nhanh

# Sửa tối thiểu — thêm vào block location hoặc server của bạn
proxy_buffer_size       128k;
proxy_buffers           4 256k;
proxy_busy_buffers_size 256k;

# Sau đó:
nginx -t && systemctl reload nginx

Related Error Notes