Chuyện gì đang xảy ra
502 có nghĩa là Nginx nhận được phản hồi lỗi hoặc không có phản hồi từ backend đang proxy tới — Node.js, PHP-FPM, Gunicorn, hoặc bất kỳ app server nào bạn đã cấu hình. Bản thân Nginx vẫn hoạt động bình thường. Vấn đề nằm ở phía upstream.
Trong thực tế, lỗi này hầu như luôn xuất phát từ một trong bốn nguyên nhân sau:
- Service upstream đã bị crash hoặc chưa được khởi động
- Địa chỉ hoặc port của upstream trong cấu hình Nginx bị sai
- Upstream bị quá tải và timeout
- Đường dẫn Unix socket không tồn tại hoặc sai quyền
Bước 1 — Kiểm tra error log của Nginx
Đừng đoán mò. Bắt đầu từ đây:
sudo tail -n 50 /var/log/nginx/error.log
Tìm một trong các dòng sau — mỗi dòng chỉ ra hướng sửa khác nhau:
# Upstream từ chối kết nối
connect() failed (111: Connection refused) while connecting to upstream
# Upstream timeout
upstream timed out (110: Connection timed out) while reading response header
# Unix socket không tồn tại
connect() to unix:/run/php/php8.1-fpm.sock failed (2: No such file or directory)
Bước 2 — Kiểm tra xem service upstream có đang chạy không
Với PHP-FPM:
sudo systemctl status php8.1-fpm
Với Node.js (PM2):
pm2 list
pm2 logs
Với Gunicorn / Django:
sudo systemctl status gunicorn
Service đã dừng hoặc bị lỗi thì cần khởi động lại:
# PHP-FPM
sudo systemctl restart php8.1-fpm
# PM2 Node.js
pm2 restart all
# Gunicorn
sudo systemctl restart gunicorn
Tải lại trang. 502 hết chưa? Xong rồi đó. Vẫn còn? Đọc tiếp.
Bước 3 — Kiểm tra địa chỉ proxy trong cấu hình Nginx
Mở file cấu hình site của bạn:
sudo nano /etc/nginx/sites-available/your-site
Tìm dòng proxy_pass hoặc fastcgi_pass:
# Node.js — port phải khớp với port app đang thực sự lắng nghe
location / {
proxy_pass http://127.0.0.1:3000;
}
# PHP-FPM — đường dẫn socket phải tồn tại trên đĩa
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
Xác nhận port app đang thực sự dùng:
sudo ss -tlnp | grep LISTEN
Kết quả mẫu:
LISTEN 0 128 127.0.0.1:3000 ... users:(("node",pid=12345))
Port không khớp? Cập nhật proxy_pass rồi reload Nginx:
sudo nginx -t && sudo systemctl reload nginx
Bước 4 — Sửa quyền socket (PHP-FPM)
Lỗi permission denied trên socket nghĩa là quyền sở hữu bị sai. Kiểm tra:
ls -la /run/php/php8.1-fpm.sock
Socket phải thuộc sở hữu của www-data (hoặc user mà Nginx đang chạy dưới). Mở file cấu hình pool của PHP-FPM:
sudo nano /etc/php/8.1/fpm/pool.d/www.conf
Ba dòng này cần khớp với user Nginx của bạn:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
Khởi động lại PHP-FPM để áp dụng:
sudo systemctl restart php8.1-fpm
Bước 5 — Xử lý timeout của upstream
Log báo upstream timed out? App của bạn đang phản hồi quá chậm. Thêm các chỉ thị timeout vào server block của Nginx:
location / {
proxy_pass http://127.0.0.1:3000;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
Reload sau khi lưu:
sudo nginx -t && sudo systemctl reload nginx
Đây chỉ là giải pháp tạm thời — không phải sửa triệt để. Nếu app liên tục chậm, hãy tìm nguyên nhân gốc rễ: truy vấn database chậm, blocking I/O, hoặc cạn kiệt tài nguyên thường là thủ phạm.
Xác nhận đã sửa xong
- Tải lại trang trên trình duyệt — lỗi 502 phải biến mất.
- Kiểm tra bằng curl:
curl -I https://yourdomain.com
HTTP/2 200 nghĩa là mọi thứ đã hoạt động. 301 hay 302 cũng không sao — đó chỉ là redirect. Bất kỳ kết quả nào không phải 5xx đều có nghĩa là Nginx đang chuyển traffic thành công tới backend.
Để error log chạy thêm một lúc để chắc chắn không có lỗi mới xuất hiện:
sudo tail -f /var/log/nginx/error.log
Tóm tắt nhanh — nguyên nhân và cách sửa lỗi 502
- Connection refused → service upstream đã dừng, khởi động lại
- No such file or directory (socket) → đường dẫn socket sai trong config, hoặc PHP-FPM chưa chạy
- Permission denied (socket) → sửa
listen.owner/listen.grouptrong pool config - Upstream timed out → tăng
proxy_read_timeout, điều tra code app bị chậm - Port sai → cập nhật
proxy_passcho khớp với port thực tế của app
Một điều cuối cùng
Hầu hết lỗi 502 đều quy về một vấn đề: Nginx không kết nối được tới backend. File log sẽ cho bạn biết chính xác lý do tại sao — đừng bỏ qua nó.
Về lâu dài, hãy chạy các service upstream dưới systemd hoặc PM2 để chúng tự động khởi động lại khi bị crash. Kết hợp thêm uptime monitoring — UptimeRobot và Better Stack đều có gói miễn phí — và bạn sẽ phát hiện sự cố tiếp theo trước khi người dùng biết.

