lionsoul2014/ip2region · critical
failed to create searcher: %s
Error message
failed to create searcher: %s
What it means
With cache_policy "file", the module creates a searcher that reads the xdb directly from disk via xdb_new_with_file_only. A non-zero return means the searcher could not be created — almost always because the file cannot be opened/read at runtime by the nginx worker/master user.
Source
Thrown at binding/nginx/src/ngx_http_ip2region_module.c:156
}
// 验证XDB文件版本是否匹配
if (xdb_version->id != expected_version->id) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"%s expects %s xdb file, but got %s: %s",
directive_name, expected_version->name, xdb_version->name, db_path);
xdb_free_header((void *)header);
if(ngx_http_ip2region_is_absolute_path(db_name) != NGX_OK) {
free(db_path);
}
return NGX_CONF_ERROR;
}
if (strcmp(cache_policy, "file") == 0) {
err = xdb_new_with_file_only(xdb_version, &ip2region_searcher->searcher, db_path);
xdb_free_header((void *)header);
if (err != 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"failed to create searcher: %s", db_path);
if(ngx_http_ip2region_is_absolute_path(db_name) != NGX_OK) {
free(db_path);
}
return NGX_CONF_ERROR;
}
} else if (strcmp(cache_policy, "vectorIndex") == 0) {
ip2region_searcher->v_index = xdb_load_vector_index_from_file(db_path);
if (ip2region_searcher->v_index == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"failed to load vector index from: %s", db_path);
xdb_free_header((void *)header);
if(ngx_http_ip2region_is_absolute_path(db_name) != NGX_OK) {
free(db_path);
}
return NGX_CONF_ERROR;
}
View on GitHub (pinned to c1a1fc7d59)
Solutions
- Verify the absolute path exists and is readable: `sudo -u www-data cat /path/to/ip2region.xdb >/dev/null`.
- chmod/chown the xdb so the nginx worker user can read it (e.g. chmod 644).
- Use an absolute path in the ip2region_cache_policy file setup to avoid cwd ambiguity.
- Check audit logs for SELinux/AppArmor denials and allow the read.
- Re-test with a freshly downloaded xdb to rule out file corruption.
Example fix
# before ip2region_db_file data/ip2region.xdb; # after ip2region_db_file /usr/share/ip2region/ip2region.xdb; # and ensure: chmod 644 /usr/share/ip2region/ip2region.xdb
Defensive patterns
Strategy: validation
Validate before calling
#!/bin/bash
f=$(awk '/ip2region_db_file /{print $2; exit}' /etc/nginx/nginx.conf | tr -d ';')
sudo -u www-data test -r "$f" && echo OK || echo "nginx user cannot read $f" Prevention
- Use absolute paths in ip2region_db_file.
- chmod 644 the xdb and ensure the nginx worker user (www-data/nginx) can read it.
- Check SELinux/AppArmor policies for the data directory.
- Re-check readability after every data refresh.
When it happens
Trigger: xdb_new_with_file_only returns != 0: file path does not exist at that absolute path, permission denied for the nginx user, or an invalid xdb handle/path passed after the earlier checks passed.
Common situations: Relative path resolving against an unexpected working directory for worker processes; file readable by root but not by the nginx worker user (www-data/nginx); SELinux/AppArmor blocking read; file moved after config was validated.
Related errors
- failed to determine xdb version from header: %s
- %s expects %s xdb file, but got %s: %s
- failed to load vector index from: %s
- failed to create vector index cached searcher: %s
- failed to load xdb content: %s
AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02).
Data as JSON: /api/errors/a39397ce484b6f5c.
Report an issue: GitHub.