Nginx 报错 "could not build server_names_hash" 怎么办?

Nginx could not build server_names_hash 的解法:调大 server_names_hash_bucket_size(域名过长时)与 server_names_hash_max_size(域名过多时),放置位置与取值规则、FAQ。

最佳实践
Nginx 报错 "could not build server_names_hash" 怎么办?封面

这个 [emerg] 错误表示 server_name 哈希表放不下你的域名配置——在 http 块里调大对应参数即可:域名太长调 server_names_hash_bucket_size,域名太多调 server_names_hash_max_size。

http {
    server_names_hash_bucket_size 128;    # 默认 32/64/128(按 CPU 缓存行)
    server_names_hash_max_size 1024;      # 默认 512
    ...
}

两个参数的分工

Nginx 用哈希表按 Host 头快速匹配 server 块,报错信息会指明是哪个参数不够:

报错文案 要调的参数 典型原因
increase server_names_hash_bucket_size server_names_hash_bucket_size 单个域名太长(如超长通配或多级子域)
increase server_names_hash_max_size server_names_hash_max_size server_name 条目总数太多

取值规则:

  • bucket_size:按 CPU 缓存行对齐,通常从 64、128、256 逐级翻倍试;报错中的数值不一定是可直接使用的最小值。
  • max_size:是哈希表大小的上限,不要求等于或超过条目数,也不要求是 2 的幂。

完整示例

# /etc/nginx/nginx.conf
http {
    server_names_hash_bucket_size 128;
    server_names_hash_max_size 2048;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

⚠️ 必须放在 http {} 块内,写在 server/location 里无效。改完:

nginx -t && systemctl reload nginx

什么时候会踩到这个坑

  • SaaS 平台给每个客户分配子域,server_name 列表几百上千条;
  • 自动化系统(泛域名证书 + 动态站点)批量生成 server 块;
  • 域名特别长:very-long-subdomain.for-a-customer.example-hosting-provider.com。

如果你的 server_name 是从数据库/脚本动态生成的,应先根据报错调整哈希参数。只有域名匹配语义确实允许时才考虑通配符;正则按顺序匹配,不能作为无差别替代。

调整参数后,除检查 reload 结果,也应检查新产生的错误日志。若已通过观测云 Nginx 集成集中采集,可按主机和变更时间查 could not build server_names_hash,确认错误是否仍在出现,再核对进程实际加载的配置。

常见问题(FAQ)

Q:两个参数都要设吗?
A:不用,报错会指明是哪个。一般只设报错提到的那个;两者有依赖关系时(bucket 变大导致总容量变化)错误提示会换文案,按提示再调即可。

Q:bucket_size 设为 1024 可以吗?
A:语法上可以,但浪费内存且没收益。正确做法是从 64/128 开始按报错提示逐级翻倍,够用即停。

Q:为什么改完 reload 还报同样的错?
A:确认写在了 http 块里而非某个 include 文件的 server 上下文;nginx -T 看磁盘配置里这行是否真的出现在 http 层级。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台