Sửa lỗi Nginx 'could not build the server_names_hash' khi cấu hình nhiều Virtual Host

intermediate Nginx2026-05-08| Nginx 1.14+ trên Ubuntu 20.04/22.04, Debian 11/12, CentOS 7/8, mọi bản phân phối Linux

Error Message

fatal: [emerg] could not build the server_names_hash, you should increase server_names_hash_bucket_size: 64
#nginx#server_name#config-error#vhost

Chuyện Gì Đã Xảy Ra

Tôi đang thêm một virtual host mới vào server Nginx đã có khoảng chục domain được cấu hình sẵn. Sau khi chạy nginx -t để kiểm tra config, tôi nhận được thông báo này:

nginx: [emerg] could not build the server_names_hash, you should increase server_names_hash_bucket_size: 64
nginx: configuration file /etc/nginx/nginx.conf test failed

Nginx từ chối reload. Site mới không lên được. Error log cũng không cung cấp thêm bất kỳ thông tin nào — chỉ có duy nhất một dòng đó. Hai dòng trong nginx.conf đã fix được, nhưng để biết hai dòng nàotại sao thì cần phải tìm hiểu thêm.

Nguyên Nhân

Nginx lưu tất cả các giá trị server_name vào một hash table để tra cứu nhanh. Mỗi bucket trong bảng đó mặc định có kích thước 64 byte. Khi một tên domain — hoặc tổng trọng lượng của tất cả các tên domain — không vừa vào bucket 64 byte, Nginx sẽ không thể khởi tạo bảng khi startup và ném ra lỗi này.

Các nguyên nhân phổ biến:

  • Tên domain dài như some-very-long-subdomain.client-company-name.example.com (dễ dàng vượt 50+ ký tự)
  • Wildcard entry như *.subdomain.example.com
  • Quá nhiều alias nhồi nhét vào một directive server_name
  • Thêm vhost mới khiến tổng kích thước hash vượt giới hạn

Các Bước Debug

Bắt đầu bằng cách xác định config nào đang gây ra vấn đề:

nginx -T 2>&1 | grep server_name

Lệnh này sẽ dump toàn bộ config đã merge. Tìm những tên bất thường dài hoặc các server block chứa nhiều alias. Sau đó chạy kiểm tra config và đọc kỹ lỗi:

sudo nginx -t

Nếu lỗi hiển thị bucket_size: 64, tăng lên 128. Nếu đã là bucket_size: 128, tăng gấp đôi lên 256.

Muốn tìm server name dài nhất nhanh chóng? Chạy lệnh này:

grep -r 'server_name' /etc/nginx/sites-enabled/ | awk '{print length, $0}' | sort -rn | head -5

Tên nào có 60–70 ký tự chính là thủ phạm. Những tên dưới 50 ký tự thường vừa vặn với bucket size mặc định 64 byte.

Cách Sửa

Mở /etc/nginx/nginx.conf và thêm hoặc cập nhật các dòng sau bên trong block http:

http {
    # Tăng hash bucket size cho server name dài
    server_names_hash_bucket_size 128;
    server_names_hash_max_size 512;

    # ... phần còn lại của config
}

Hai directive này giải quyết các vấn đề khác nhau:

  • server_names_hash_bucket_size — kiểm soát kích thước từng bucket riêng lẻ. Phải là lũy thừa của 2: 64 → 128 → 256. Tăng giá trị này khi một tên domain quá dài không vừa bucket.
  • server_names_hash_max_size — kiểm soát tổng số bucket. Mặc định là 512. Chỉ cần quan tâm khi bạn đang host hàng trăm domain — hầu hết mọi người không cần đụng đến cái này.

Với server thông thường gặp lỗi này, chỉ cần server_names_hash_bucket_size 128 là đủ. Đặt thẳng 256 từ đầu cũng không tốn kém gì và giúp bạn có thêm dư địa cho các domain trong tương lai.

Áp Dụng Fix

# Kiểm tra config trước — luôn luôn
sudo nginx -t

# Nếu test thành công, reload
sudo systemctl reload nginx

Xác Minh

Kết quả test sạch trông như thế này:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Sau đó xác nhận service đang chạy và vhost mới phản hồi được:

sudo systemctl status nginx
curl -I http://your-new-domain.com

Debug từ xa hoặc qua load balancer? Kiểm tra trực tiếp các worker process:

ps aux | grep nginx

Bạn sẽ thấy một master process và ít nhất một worker. Nếu chỉ có master mà không có worker nghĩa là vẫn còn thứ gì đó load thất bại.

Các Trường Hợp Đặc Biệt

Lỗi Vẫn Còn Sau Khi Đặt 128

Nếu lỗi bây giờ hiển thị bucket_size: 128, bạn đang có một tên domain thực sự rất dài. Nhảy thẳng lên 256:

server_names_hash_bucket_size 256;

Chỉ dùng lũy thừa của 2. Đặt giá trị như 192 sẽ không hoạt động — Nginx sẽ tự động làm tròn xuống hoặc ném ra một lỗi khác.

Config Nằm Trong File Include Riêng

Một số distro tách nginx.conf thành nhiều file include. Hãy đảm bảo directive nằm trong block http, không phải block server:

nginx -T 2>&1 | grep -A2 -B2 'server_names_hash'

Nếu vô tình đặt vào trong block server, directive sẽ bị bỏ qua hoàn toàn — lỗi cứ lặp lại và bạn sẽ mất cả tiếng đồng hồ tự hỏi tại sao.

Phòng Ngừa

Hiện tại, hai dòng này được thêm vào mọi cài đặt Nginx mới trước khi cấu hình bất kỳ vhost nào:

server_names_hash_bucket_size 128;
server_names_hash_max_size 1024;

Mất 10 giây. Tránh cho bạn khỏi một lần reload thất bại lúc 2 giờ sáng khi ai đó thêm domain kiểu như staging-api.long-client-name.internal.example.com.

Nếu bạn quản lý nhiều server Nginx và muốn kiểm tra config trước khi đẩy lên, nginx -t -c /path/to/test.conf cho phép bạn test bản sao local trước khi deploy. Để xác minh rằng config đã test khớp byte-for-byte với những gì đang chạy trên server, tôi dùng SHA-256 check với Hash Generator tại toolcraft.app — chạy trên trình duyệt, không có gì được upload lên.

Bài Học Rút Ra

  • Luôn chạy nginx -t trước khi systemctl reload nginx. Reload với config lỗi sẽ thất bại âm thầm — config cũ vẫn chạy và bạn không nhận được cảnh báo nào.
  • Mặc định 64 byte ổn với các tên ngắn. Nhưng ngay khi ai đó thêm subdomain như portal.north-america-region.client.example.com, bạn đã vượt giới hạn. Đặt 128 từ ngày đầu.
  • Thông báo lỗi hơi gây nhầm lẫn. Nó chỉ vào bucket_size, nhưng nếu bạn đang host 300+ domain, max_size mới là thứ thực sự cần điều chỉnh. Hãy kiểm tra cả hai.
  • Lỗi này chỉ xuất hiện lúc load config — khi khởi động hoặc reload. Server chạy ổn hàng tháng có thể đột ngột từ chối reload sau một thay đổi config duy nhất. Trước đó không có gì hỏng cả; chỉ là tên mới vừa đẩy vượt ngưỡng giới hạn.

Related Error Notes