bigywater.tech
常见报错 · 37

Nginx [emerg] 启动失败:15 个常见配置错误的 nginx -t 原文,nginx -t 通过仍会 bind() failed,reload 失败时旧配置继续生效

“nginx: [emerg] …” 是 nginx 启动和 reload 失败时的所有报错的前缀。这篇在本机用自己的 nginx 把常见的配置错误一个个构造出来,记录 nginx -t 的原文,再测 nginx -t 通过却启动失败、reload 失败后旧配置是否继续生效,以及 proxy_pass 里域名解析的两种写法。

15
本篇用 nginx -t 逐个测试的错误配置个数,其中 13 个失败、2 个不会失败
48
bind() 失败括号里的编号(macOS 的 EADDRINUSE);nginx -t 并不检查端口是否被占
旧配置
reload 时配置有错,nginx 继续用旧配置,新配置不会半截生效

配置错误的原文

实测 · 本机执行输出
  指令名拼错(退出码 1):
      nginx: [emerg] unknown directive "locatoin" in nginx.conf:8
      nginx: configuration file nginx.conf test failed
  指令后面漏了分号(退出码 1):
      nginx: [emerg] directive "listen" is not terminated by ";" in nginx.conf:8
      nginx: configuration file nginx.conf test failed
  return 少了分号就直接接 }(退出码 1):
      nginx: [emerg] unexpected "}" in nginx.conf:8
      nginx: configuration file nginx.conf test failed
  多了一个 }(退出码 1):
      nginx: [emerg] unexpected "}" in nginx.conf:10
      nginx: configuration file nginx.conf test failed
  少了一个 }(退出码 1):
      nginx: [emerg] unexpected end of file, expecting "}" in nginx.conf:10
      nginx: configuration file nginx.conf test failed
  指令放错位置(server 里写 upstream)(退出码 1):
      nginx: [emerg] "upstream" directive is not allowed here in nginx.conf:8
      nginx: configuration file nginx.conf test failed
  参数个数不对(退出码 1):
      nginx: [emerg] invalid number of arguments in "listen" directive in nginx.conf:8
      nginx: configuration file nginx.conf test failed
  用了没定义的变量(退出码 1):
      nginx: [emerg] unknown "no_such_var" variable
      nginx: configuration file nginx.conf test failed
  同一个 server 里两个相同的 location(退出码 1):
      nginx: [emerg] duplicate location "/a" in nginx.conf:8
      nginx: configuration file nginx.conf test failed
  include 的文件不存在(退出码 1):
      nginx: [emerg] open() "<tmp>/conf.d/missing.conf" failed (2: No such file or directory) in nginx.conf:8
      nginx: configuration file nginx.conf test failed
  include 通配符没有匹配到文件(退出码 0):
      nginx: the configuration file nginx.conf syntax is ok
  证书文件不存在(退出码 1):
      nginx: [emerg] cannot load certificate "<tmp>/nope.pem": BIO_new_file() failed (SSL: error:80000002:system library::No such file or directory:calling fopen(<tmp>/nope.pem, r) error:10000080:BIO routin
      nginx: configuration file nginx.conf test failed
  proxy_pass 的主机名解析不了(退出码 1):
      nginx: [emerg] host not found in upstream "nonexistent-host.invalid" in nginx.conf:8
      nginx: configuration file nginx.conf test failed
  日志目录不存在(退出码 1):
      nginx: [emerg] open() "<tmp>/nodir/access.log" failed (2: No such file or directory)
      nginx: configuration file nginx.conf test failed
  同一个端口重复 listen 同一个 server_name(退出码 0):
      nginx: [warn] conflicting server name "a.test" on 127.0.0.1:9780, ignored

大多数带文件名和行号;unknown variable 和日志目录那两个没有行号。

不会失败的错误

实测 · 本机执行输出
  nginx -t:nginx: configuration file <tmp>/nginx.conf test is successful
  第二个 nginx(另一个 pid 文件)用同一个端口启动(退出码 1):
      nginx: [emerg] bind() to 127.0.0.1:9780 failed (48: Address already in use)
      nginx: [emerg] bind() to 127.0.0.1:9780 failed (48: Address already in use)
      …(共 6 行,同样的 bind() 失败会重试几次)
  别的程序占着 9781,nginx -t(退出码 0):nginx: configuration file <tmp>/nginx.conf test is successful
  真正启动(退出码 1):
      nginx: [emerg] bind() to 127.0.0.1:9781 failed (48: Address already in use)
      nginx: [emerg] bind() to 127.0.0.1:9781 failed (48: Address already in use)

include 通配符没匹配到文件静默通过;重复的 server_name 只是警告。

nginx -t 通过仍失败

实测 · 本机执行输出
  reload 前:version 1
  配置里 return 拼成 retrun 之后 nginx -s reload(退出码 1):
      nginx: [emerg] unknown directive "retrun" in nginx.conf:8
  reload 之后访问:version 1(仍然是旧配置)
  改好之后再 reload:version 2

端口被占用只会在真正启动时暴露。

reload

实测 · 本机执行输出
  用变量:nginx -t(退出码 0):nginx: configuration file <tmp>/nginx.conf test is successful
  请求时:HTTP 502
      error.log: [error] *2 no resolver defined to resolve nonexistent-host.invalid, request: "GET / HTTP/1.1", host: "127.0.0.1:9780"
  配了一个连不上的 resolver(127.0.0.1:9):HTTP 502,耗时 1.00 s
      error.log: [error] recv() failed (61: Connection refused) while resolving, resolver: 127.0.0.1:9
      error.log: [error] *2 nonexistent-host.invalid could not be resolved (60: Operation timed out), request: "GET / HTTP/1.1", host: "127.0.0.1:9780"

配置有错时旧配置继续生效;先 nginx -t 再 reload。

域名解析

实测 · 本机执行输出
  非 root 监听 127.0.0.1:80:失败(退出码 1):nginx: [emerg] bind() to 127.0.0.1:80 failed (13: Permission denied)
  非 root 运行时配置了 user nobody;nginx -t(退出码 0):
      nginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in nginx.conf:3
      nginx: the configuration file nginx.conf syntax is ok

写死域名启动时解析;用变量推迟到请求时,需要 resolver。

分步演示

启动失败
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64;报错文本都是真实复现时原样捕获的(命令行工具统一用 LC_ALL=C 取英文原文,路径换成 );所有服务都是本机上自己起的、只监听 127.0.0.1,不访问外网;计时用 time.perf_counter,数字每次运行会有小幅抖动。本篇用 nginx/1.31.7(Homebrew);每个实验用自己的前缀目录和配置,需要启动的只监听 127.0.0.1 上 9780 以上的端口(为测非 root 监听 80 临时尝试过 127.0.0.1:80,没有成功);域名解析失败用保留域名 .invalid 触发,这个查询会交给系统的 DNS 解析器;errno 编号(48、13、61、60)是 macOS 上的
    • 没有验证:Linux 上 bind() 失败的 errno 编号(98、13)与 SELinux 的影响;systemd 下 nginx 启动失败时 journalctl 的写法;ssl_certificate 与私钥不匹配(key values mismatch)、证书链问题;listen ... reuseport 的行为;用 root 启动并切换 user 之后的权限错误(如日志目录权限);nginx 其他版本里报错措辞的差异;include 的相对路径是相对于 prefix 还是配置文件(本篇都使用了自己的前缀目录)
    京ICP备2026067502号-1京公网安备11010502063487号