nginx运行时“未知变量”错误源于未定义或拼错的变量(如$reqeust_time),导致log_format、proxy_pass等行为异常;需通过error.log定位变量名,区分日志变量、http头变量和自定义变量三类,并用最小化access_log测试验证,结合文档复制、编辑器补全和ci校验预防。

Linux Nginx 配置文件中出现“未知变量”提示,通常不是 nginx -t 报错,而是运行时在 error.log 中看到 unknown log variable 或代理/重写行为异常(如 proxy_pass 变成空地址、rewrite 结果为空)。这是因为 Nginx 对未定义变量默认视为空字符串,不中断启动,但会导致逻辑错误。
看 error.log 定位具体变量名
直接搜索错误日志(通常是 /var/log/nginx/error.log)中的关键词:
-
unknown log variable—— 明确指出哪个变量名拼错了,比如"reqeust_time"(少 u)或"upstrem_addr"(少 r) -
connect() failed (99: Cannot assign requested address)—— 常见于proxy_pass $backend_url中变量拼错,展开后变成proxy_pass ; -
invalid URL prefix或no resolver defined—— 也可能源于变量为空导致协议/域名缺失
确认变量是否属于合法内置变量或已正确定义
区分三类情况:
-
日志变量(仅用于
log_format):必须是 Nginx 官方支持的,如$request_time、$upstream_response_time。拼错、大小写错、下划线漏掉都会被拒 -
HTTP 头变量:请求头转为
$http_x_forwarded_for(X-Forwarded-For→ 下划线+全小写),响应头是$sent_http_content_type,不是$http_content_type -
自定义变量(
set或map定义):需检查作用域是否覆盖使用位置。例如set $api_host写在http块,可在所有server和location中用;若写在另一个location里,则当前块不可见
快速验证可疑变量是否有效
不依赖真实业务流量,用最小化测试确认:
- 临时加一条极简
access_log,只输出该变量:log_format test '$my_var';<br>access_log /dev/stdout test;
- 执行
nginx -t确保语法无误 - 发一次请求:
curl -I http://localhost - 立刻查
error.log:如果报unknown log variable "my_var",就坐实拼写或不存在问题 - 也可用
nginx -T 2>&1 | grep -A3 -B3 '\$[a-z_]+'提取所有带$的行,人工比对定义与引用
预防下次再出错
减少手写变量带来的风险:
- 从 Nginx 官方日志变量文档 复制粘贴,不手动敲
- 编辑器启用 Nginx 插件(如 VS Code 的 “Nginx Configuration”),支持变量自动补全和高亮
- 团队内维护一份标准
log_format模板,禁止自由发挥新增变量 - CI 流程中加入简单校验脚本:提取所有
$xxx,对照白名单正则匹配











