TL;DR: Cách khắc phục nhanh
Khi các header trở nên quá lớn so với thiết lập mặc định của Nginx, nó sẽ trả về lỗi 431. Bạn có thể khắc phục điều này bằng cách tăng kích thước bộ đệm header trong cấu hình của mình. Mở tệp cấu hình Nginx (thường là /etc/nginx/nginx.conf hoặc tệp cấu hình riêng cho trang web trong /etc/nginx/sites-available/) và thêm chỉ thị này vào khối http, server, hoặc location:
http {
# Tăng kích thước bộ đệm lên 16k hoặc 32k
large_client_header_buffers 4 16k;
# ... các cấu hình khác
}
Sau khi lưu các thay đổi, hãy kiểm tra cú pháp và tải lại dịch vụ:
sudo nginx -t
sudo systemctl reload nginx
Tại sao lỗi này xảy ra
Trạng thái 431 Request Header Fields Too Large có nghĩa là các HTTP header được gửi bởi client—như trình duyệt hoặc ứng dụng di động—quá lớn để máy chủ có thể xử lý. Mặc dù đặc tả HTTP không đặt ra giới hạn cứng, Nginx sử dụng các bộ đệm mặc định nhỏ để bảo vệ máy chủ của bạn khỏi các cuộc tấn công làm cạn kiệt bộ nhớ (memory exhaustion).
Bạn có thể sẽ gặp vấn đề này khi xử lý:
- **JWT Token quá lớn:** Các token chứa nhiều custom claim hoặc các đối tượng metadata lớn.
- **Tích tụ Cookie:** Khi ứng dụng của bạn và các công cụ bên thứ ba (như Google Analytics hoặc HubSpot) thiết lập hàng chục cookie, tổng header `Cookie` có thể dễ dàng vượt quá 8KB.
- **Xác thực doanh nghiệp:** Các header xác thực phức tạp được sử dụng trong môi trường SSO của doanh nghiệp.
Nginx quản lý các giới hạn này thông qua client_header_buffer_size (cho dòng yêu cầu ban đầu) và large_client_header_buffers. Chỉ thị thứ hai hầu như luôn là nguyên nhân gây ra lỗi 431.
Các phương pháp khắc phục chi tiết
1. Cấu hình toàn cục (Global)
Cập nhật cấu hình toàn cục là cách nhanh nhất để khắc phục vấn đề cho tất cả các trang web của bạn. Đây là quy trình tiêu chuẩn cho các API gateway chuyên dụng xử lý lưu lượng xác thực lớn.
# Chỉnh sửa cấu hình chính
sudo nano /etc/nginx/nginx.conf
Bên trong khối http, hãy chèn chỉ thị sau:
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# '4' là số lượng bộ đệm; '16k' là kích thước của mỗi bộ đệm
large_client_header_buffers 4 16k;
# ...
}
2. Khắc phục cho từng khối Server cụ thể
Nếu chỉ có một ứng dụng cụ thể—chẳng hạn như frontend sử dụng các token Auth0 nặng—gây ra lỗi, hãy chỉ áp dụng bản sửa lỗi cho virtual host cụ thể đó.
server {
listen 443 ssl;
server_name api.example.com;
# Chỉ áp dụng cho domain này
large_client_header_buffers 4 32k;
location / {
proxy_pass http://backend_upstream;
}
}
3. Chọn kích thước bộ đệm phù hợp
Hầu hết các bản build Nginx mặc định là 4 8k. Điều này có nghĩa là Nginx cấp phát bốn bộ đệm 8KB cho các header. Nếu một header đơn lẻ—như JWT chứa nhiều vai trò người dùng—đạt mức 10KB, yêu cầu sẽ thất bại vì nó không vừa với một ngăn 8KB.
- **16k:** Mức lý tưởng cho hầu hết các ứng dụng sử dụng JWT lớn.
- **32k:** Sử dụng mức này nếu bạn có các hệ thống cũ hoặc dữ liệu cookie cực kỳ nặng.
- **64k:** Chỉ sử dụng nếu thực sự cần thiết; rất hiếm khi cần nhiều hơn 32KB.
Cách xác minh bản sửa lỗi
Sau khi bạn đã tải lại Nginx, hãy xác nhận rằng lỗi đã biến mất. Bạn có thể sử dụng curl để mô phỏng một header lớn mà không cần thao tác trên trình duyệt.
Chạy lệnh này để gửi một header 10KB giả lập đến máy chủ của bạn:
# Tạo một header giả 10KB
LONG_HEADER=$(printf 'X-Custom-Header: %.0sA' {1..10000})
curl -I -H "$LONG_HEADER" http://localhost/
Kết quả: Bạn sẽ thấy mã HTTP/1.1 200 OK hoặc một lệnh chuyển hướng thay vì lỗi 431.
Bảo mật và Tác dụng phụ
Cân bằng giữa bộ nhớ và an toàn
Mỗi bộ đệm bạn cấp phát đều tiêu tốn bộ nhớ. Mặc dù việc tăng từ 8KB lên 32KB sẽ không ảnh hưởng đến máy chủ có 8GB RAM, nhưng thiết lập nó thành 1MB có thể gây nguy hiểm. Kẻ tấn công có thể làm cạn kiệt bộ nhớ của bạn bằng cách mở hàng nghìn kết nối đồng thời với các header khổng lồ. Hãy giữ ở kích thước nhỏ nhất có thể giải quyết được vấn đề của bạn.
Giới hạn của trình duyệt
Đừng quên trình duyệt. Chrome và Firefox có giới hạn riêng, thường khoảng 8KB đến 16KB cho mỗi header đơn lẻ. Nếu Nginx đã thông thoáng nhưng người dùng vẫn gặp lỗi, đã đến lúc chuyển dữ liệu ra khỏi cookie và đưa vào thân yêu cầu (POST) hoặc localStorage.
Bộ cân bằng tải phía trên (Upstream Load Balancers)
Nếu ứng dụng của bạn nằm sau AWS ALB hoặc Cloudflare, hãy đảm bảo các dịch vụ đó hỗ trợ kích thước header mới của bạn. Ví dụ, Cloudflare có giới hạn cứng là 32KB cho tổng tất cả các header cộng lại. Nếu bạn vượt quá mức đó, Cloudflare sẽ trả về lỗi của chính nó trước khi yêu cầu kịp đến được Nginx.

