nginx/nginx · error
NGX_LOG_CRIT
NGX_LOG_CRIT
Error message
<ngx_open_file_n> \"%s\" failed
What it means
Logged by ngx_stream_geo_include_binary_base(): opening the precompiled range base file ('<include>.bin') with ngx_open_file() failed with an errno other than NGX_ENOENT - typically EACCES. Missing files (ENOENT) are silent because the normal case is 'no .bin yet'. The function returns NGX_DECLINED so nginx falls back to parsing the text include file; startup only fails if that also fails.
Source
Thrown at src/stream/ngx_stream_geo_module.c:1371
ngx_err_t err;
ngx_int_t rc;
ngx_uint_t i;
ngx_file_t file;
ngx_file_info_t fi;
ngx_stream_geo_range_t *range, **ranges;
ngx_stream_geo_header_t *header;
ngx_stream_variable_value_t *vv;
ngx_memzero(&file, sizeof(ngx_file_t));
file.name = *name;
file.log = cf->log;
file.fd = ngx_open_file(name->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
if (file.fd == NGX_INVALID_FILE) {
err = ngx_errno;
if (err != NGX_ENOENT) {
ngx_conf_log_error(NGX_LOG_CRIT, cf, err,
ngx_open_file_n " \"%s\" failed", name->data);
}
return NGX_DECLINED;
}
if (ctx->outside_entries) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"binary geo range base \"%s\" cannot be mixed with usual entries",
name->data);
rc = NGX_ERROR;
goto done;
}
if (ctx->binary_include) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"second binary geo range base \"%s\" cannot be mixed with \"%s\"",
name->data, ctx->include_name.data);
rc = NGX_ERROR;View on GitHub (pinned to 3f6f7824d4)
Solutions
- Check the exact path printed in the message and run `ls -l <file>.bin` and `sudo -u <nginx-user> cat <file>.bin` to confirm readability
- Fix permissions: `chown <nginx-user> <file>.bin; chmod 644 <file>.bin` (and +x on parent dirs)
- Adjust SELinux context (`restorecon`) or the AppArmor profile if applicable
- As a workaround delete the .bin - nginx re-parses the text file and regenerates it
Example fix
# before: .bin written by root with 600 $ ls -l /etc/nginx/geo/geo.conf.bin -rw------- root root /etc/nginx/geo/geo.conf.bin # after: readable by master process user $ chown nginx:nginx /etc/nginx/geo/geo.conf.bin $ chmod 644 /etc/nginx/geo/geo.conf.bin
Defensive patterns
Strategy: validation
Validate before calling
# pre-flight: master-process user must be able to read text + .bin for f in /etc/nginx/geo/*.conf /etc/nginx/geo/*.conf.bin; do [ -e "$f" ] && sudo -u nginx test -r "$f" || echo "UNREADABLE: $f" done
Prevention
- Set ownership/permissions on the conf directory and geo files in your deploy script
- Beware umask when generating .bin files as root
- Check SELinux/AppArmor contexts after moving geo files
When it happens
Trigger: A `<name>.bin` exists next to the include file but the master process user cannot open it (permission bits, non-searchable parent directory, SELinux/AppArmor denial), so ngx_open_file() returns NGX_INVALID_FILE with err != NGX_ENOENT.
Common situations: The .bin was generated by root with restrictive umask while nginx runs as another user; security modules blocking access; containers with read-only or odd permission mounts.
Related errors
- NGX_LOG_EMERG
- NGX_LOG_WARN
- NGX_LOG_ALERT
- NGX_LOG_EMERG
- [alert] could not open error log file: \"%s\" failed
AI-assisted analysis of nginx/nginx@3f6f7824d4 (2026-08-22).
Data as JSON: /api/errors/343d6f6d60d7c9f0.
Report an issue: GitHub.