Sửa lỗi Nginx: upstream prematurely closed connection while reading response header

intermediate Nginx2026-06-23| Linux (Ubuntu/CentOS/Debian), Nginx 1.18+, Backend (Node.js, Gunicorn, PHP-FPM, Go)

Error Message

upstream prematurely closed connection while reading response header from upstream
#nginx#upstream#timeout#backend-crash

Thông báo lỗi

Khi kiểm tra nhật ký lỗi (error logs) của Nginx (thường nằm tại /var/log/nginx/error.log), bạn có thể bắt gặp dòng thông báo cụ thể sau:

[error] 1234#0: *5678 upstream prematurely closed connection while reading response header from upstream, client: 1.2.3.4, server: example.com, request: "POST /api/data HTTP/1.1", upstream: "http://127.0.0.1:8080/api/data"

Nguyên nhân gốc rễ

Lỗi này cho biết Nginx đã kết nối thành công với backend (upstream) và gửi yêu cầu, nhưng backend đã đóng kết nối TCP trước khi gửi xong các header phản hồi HTTP. Điều này thường xảy ra do bốn lý do sau:

  • Backend bị treo (Crash): Tiến trình ứng dụng (Node.js, Python, PHP) bị crash hoặc bị buộc dừng (OOM) trong khi đang xử lý yêu cầu.
  • Lệch thời gian chờ (Timeout Mismatch): Backend có thời gian chờ ngắn hơn Nginx và ngắt kết nối khi vẫn đang xử lý.
  • Tràn bộ đệm (Buffer Overflow): Các header phản hồi từ backend quá lớn so với cấu hình buffer hiện tại của Nginx.
  • Vấn đề Keep-alive: Backend đã đóng một kết nối bền vững (persistent connection) mà Nginx vẫn cho rằng đang mở.

Các bước khắc phục

1. Kiểm tra trạng thái hoạt động của ứng dụng backend

Nguyên nhân phổ biến nhất là dịch vụ backend gặp lỗi giữa chừng. Hãy kiểm tra log ứng dụng ngay lập tức. Ví dụ, nếu bạn dùng systemd:

# Kiểm tra trạng thái dịch vụ và các log gần đây
journalctl -u my-backend-service -n 50 --no-pager

Tìm các lỗi Segmentation Fault, Out of Memory (OOM) hoặc các ngoại lệ (exceptions) chưa được xử lý. Nếu backend bị crash, hãy sửa mã nguồn hoặc tăng RAM máy chủ trước khi điều chỉnh cấu hình Nginx.

2. Tăng kích thước Proxy Buffer

Nếu ứng dụng của bạn gửi cookie lớn hoặc nhiều header tùy chỉnh, Nginx có thể ngắt kết nối vì header vượt quá kích thước bộ đệm. Thêm các chỉ thị sau vào khối location hoặc http:

location / {
    proxy_buffer_size          128k;
    proxy_buffers              4 256k;
    proxy_busy_buffers_size    256k;
    proxy_pass http://your_backend;
}

Sau khi lưu, hãy kiểm tra và tải lại Nginx:

nginx -t && systemctl reload nginx

3. Đồng bộ cài đặt Keep-Alive

Nếu Nginx cố gắng sử dụng lại một kết nối mà backend đã hết thời gian chờ và đóng lại, lỗi này sẽ xảy ra. Đảm bảo Nginx và backend thống nhất về thời gian giữ kết nối. Hãy thử tắt proxy_keepalive hoặc đảm bảo timeout của backend dài hơn của Nginx.

Trong khối upstream của bạn:

upstream my_backend {
    server 127.0.0.1:8080;
    keepalive 32;
    keepalive_requests 100;
    keepalive_timeout 60s;
}

Nếu lỗi vẫn tiếp diễn, hãy thử thiết lập proxy_http_version 1.1;proxy_set_header Connection ""; để xử lý keep-alive đúng cách.

4. Tăng thời gian chờ thực thi của Backend

Nếu backend mất quá nhiều thời gian để phản hồi, nó có thể chạm giới hạn timeout nội bộ (như max_execution_time trong PHP hoặc timeout trong Gunicorn) và đóng socket. Hãy tăng các giá trị này để khớp với proxy_read_timeout của Nginx.

Ví dụ cho Nginx:

location /api/ {
    proxy_read_timeout 300s;
    proxy_connect_timeout 300s;
    proxy_send_timeout 300s;
    proxy_pass http://your_backend;
}

Kiểm tra kết quả

Để xác nhận việc sửa lỗi, hãy sử dụng curl để kiểm tra endpoint cụ thể đang gặp lỗi:

curl -I -X POST https://example.com/api/data

Theo dõi log lỗi trong thời gian thực khi thực hiện yêu cầu:

tail -f /var/log/nginx/error.log

Nếu lỗi HTTP 502/504 biến mất và không có mục "prematurely closed" mới nào xuất hiện, cấu hình đã ổn định.

Phòng ngừa

  • Giám sát (Monitoring): Thiết lập cảnh báo cho các mã trạng thái 5xx và việc khởi động lại tiến trình backend.
  • Giới hạn tài nguyên: Đảm bảo backend có đủ file descriptors (ulimit -n) để xử lý các kết nối đồng thời.
  • Đóng ứng dụng an toàn (Graceful Shutdown): Đảm bảo ứng dụng của bạn xử lý tín hiệu SIGTERM một cách mượt mà để không ngắt các kết nối đang hoạt động trong quá trình triển khai (deployment).

Related Error Notes