排查 server_name 冲突核心是确认“谁真正生效”,Nginx 静默忽略后加载重复项,按精确匹配>通配符>正则顺序筛选,未匹配时交由 default_server 或端口首个块兜底;须用 nginx -T 查合并配置、搜冲突警告、实测请求路由。

排查 server_name 匹配顺序混乱,核心不是看“写了什么”,而是确认“谁真正生效”。Nginx 不报错、不中断,只默默把请求交给错误的 server 块——比如你访问 api.example.com,结果返回的是默认站或测试站的页面。
查最终加载的配置结构
用 nginx -T 输出完整合并后的配置(含所有 include),直接定位你的域名:
-
nginx -T 2>/dev/null | grep -A 10 "server_name.*api\.example\.com"—— 查该域名是否被加载、在哪一个文件里、是否重复出现 -
nginx -T 2>/dev/null | grep "listen.*443" -A 5—— 列出所有监听 443 的 server 块,观察 default_server 标记和定义顺序 - 重点找警告:如
conflicting server name "api.example.com" on 0.0.0.0:443, ignored,说明后加载的块已被静默丢弃
验证匹配优先级是否被绕过
Nginx 按固定顺序比对,不是“找到就停”,而是逐级筛选。常见误判点:
- 只配了
server_name api.example.com,但用户访问的是www.api.example.com或https://api.example.com:8443—— 这些都不匹配,会掉进 default_server 或第一个块 -
*.example.com不匹配example.com,必须显式加example.com - 正则匹配(如
~^api\..*)一旦命中,立刻终止,后续更精确的块也无效
实测真实请求路由路径
别依赖文件名或目录位置,用真实请求验证哪个块响应:
- 临时把疑似主配置重命名为
00-api.conf,重启 Nginx;如果原来 404 的接口突然通了,说明是加载顺序或兜底冲突 - 用
curl -H "Host: api.example.com" http://127.0.0.1绕过 DNS 直连,确认是否仍进错块 - 在可疑的兜底块里加
return 444;或写独立 access_log,看是否有意外 Host 头打进来
检查 default_server 和隐式兜底行为
没设 default_server ≠ 安全。Nginx 会把同一端口下第一个定义的 server 块当作隐式兜底:
- IP 直接访问(如
http://192.168.1.100)时,Host 头为空,必然落入 default_server 或第一个块 - 查所有监听 80/443 的块:
nginx -T 2>/dev/null | awk '/^server {/,/^}/ {if (/listen.*443/) print FILENAME ":" NR; if (/server_name/) print " " $0}' - 确保兜底配置(如
99-default.conf)明确带default_server,且不含干扰性 server_name



















