nginx报unknown variable错误是因log_format中引用了非法变量,需检查拼写、大小写、模块加载及变量作用域。

当 Nginx 启动或重载配置时提示类似 unknown variable 的错误,比如:
nginx: [emerg] unknown variable "upstream_http_x_trace_id" in /etc/nginx/nginx.conf:35
这说明你在 log_format 中引用了一个 Nginx 无法识别的变量,常见于拼写错误、模块未启用、变量作用域不匹配或大小写错误。
确认变量是否真实存在且拼写正确
Nginx 内置变量(如 $remote_addr、$status)和第三方模块提供的变量(如 $upstream_http_*、$sent_http_*)都有明确命名规则。注意:
-
$upstream_http_XXX只在有 upstream 块且后端实际返回了对应 header 时才有效,但定义log_format时不需要后端已响应——只要变量名合法,Nginx 就接受; -
$sent_http_XXX是响应 header,必须以小写下划线格式,不能写成$sent_http_Content_Type; - 检查大小写:Nginx 变量严格区分大小写,
$request_time正确,$Request_time就报错; - 确认是否多打了下划线或少写了前缀,例如误写
$upstream_http__x_trace_id(双下划线)或$http_x_trace_id(漏掉upstream_却想取上游响应头)。
验证变量所属模块是否已加载
部分变量依赖特定模块。例如:
-
$request_id来自ngx_http_core_module(默认内置,无需额外编译); -
$upstream_connect_time、$upstream_header_time等需确保使用了http_upstream_module(通常默认启用); - 若用了 OpenResty 或自定义模块(如
lua-nginx-module提供的$lua_var),要确认该模块已编译进 Nginx,并在配置中正确初始化(如通过set_by_lua定义过); - 运行
nginx -V 2>&1 | grep -o with-http.*-module查看已编译模块列表,辅助判断变量支持情况。
区分请求阶段变量与日志变量的可用性
不是所有变量都能用于 log_format。Nginx 日志格式仅支持“可在日志写入时刻确定值”的变量,例如:
- ✅ 支持:
$time_local、$status、$upstream_status、$http_referer、$body_bytes_sent; - ❌ 不支持:
$arg_xxx(虽可读,但部分旧版本不支持,建议用$args替代)、$cookie_xxx(同理,低版本可能不支持)、$request_body(除非开启lua_need_request_body on且用 Lua 注入,否则不可用); - ⚠️ 特别注意:
$upstream_http_*类变量在无 upstream 转发时值为空,但不会报错;而$upstream_addr在非 proxy 场景下也为空,但定义本身合法。
快速定位与修复步骤
按顺序执行以下操作:
- 运行
nginx -t,捕获完整报错行号和变量名; - 打开对应配置文件,定位到
log_format行,逐个核对变量名是否在官方变量文档或对应模块文档中存在; - 临时注释掉疑似问题变量,再
nginx -t测试,逐步缩小范围; - 如果变量来自自定义逻辑(如 Lua 设置),确认
set_by_lua或rewrite_by_lua已在 server/location 中声明,且变量名与日志中引用的一致; - 重启前始终用
nginx -t验证,避免配置热加载失败导致服务中断。











