GeoIP2数据库加载失败主因是路径、权限或配置位置错误:需确认GeoLite2-Country.mmdb存在且nginx worker用户可读(权限≥644),geoip2指令必须置于http块顶层,配合set_real_ip_from还原真实IP,否则变量为空。

GeoIP2数据库加载失败,通常不是模块没装好,而是路径、权限或配置位置出错。排查要从数据库本身开始,再逐层向上验证。
检查数据库文件是否存在且可读
GeoLite2-Country.mmdb 必须放在 Nginx worker 进程能访问的路径下(如 /usr/share/GeoIP/GeoLite2-Country.mmdb),且文件权限需允许 nginx 用户(通常是 www-data 或 nginx)读取:
- 运行 ls -l /path/to/GeoLite2-Country.mmdb,确认属组和权限(至少 644)
- 用 sudo -u www-data stat /path/to/GeoLite2-Country.mmdb 测试能否被 worker 用户访问
- 若使用 systemd 启动,注意 ProtectSystem=strict 可能阻止读取非标准路径,需调整服务配置
确认 geoip2 指令写在正确作用域
geoip2 指令必须位于 http 块顶层(不能在 server、location 或 upstream 内),否则会静默失效或报错:
- 错误写法:server { geoip2 /path/... }
- 正确写法:http { geoip2 /path/...; ... }
- 同时确保该指令前没有语法错误(如漏掉分号、引号不闭合),否则整个 http 块解析中断
验证模块已加载且数据库被识别
仅靠 nginx -V 看到模块名还不够,要确认运行时是否真正加载了数据库:
- 启动后执行 nginx -T 2>/dev/null | grep -A5 'geoip2',检查输出中是否完整显示你配置的路径
- 查看 /var/log/nginx/error.log,加载失败时通常有类似 "geoip2: failed to open database" 或 "invalid database file" 的提示
- 若用 auto_reload 参数,注意它只对文件修改时间敏感,不校验内容有效性;首次加载失败时 auto_reload 不会触发重试
留意 CDN 或代理导致的 IP 错位
如果前端有 CDN、LB 或反向代理,Nginx 默认拿到的是代理 IP,而非真实客户端 IP,geoip2 就会查错:
- 必须配合 set_real_ip_from + real_ip_header 正确还原源 IP(如 X-Forwarded-For)
- 未配置或配置错误时,$geoip2_data_country_code 变量始终为空,但不会报错,容易误判为数据库问题
- 可在日志中临时加 log_format debug '$remote_addr — $realip_remote_addr — $geoip2_data_country_code'; 对比验证


















