lionsoul2014/ip2region · critical

failed to create vector index cached searcher: %s

Error message

failed to create vector index cached searcher: %s

What it means

nginx module init-time failure: the searcher could not be created with the vectorIndex cache policy because xdb_load_vector_index_from_file returned NULL — the vector index block could not be loaded from the configured db file (missing, unreadable, or too short). The directive returns NGX_CONF_ERROR and worker startup aborts.

Source

Thrown at binding/nginx/src/ngx_http_ip2region_module.c:178

            }
            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;
        }

        err = xdb_new_with_vector_index(xdb_version, &ip2region_searcher->searcher, db_path, ip2region_searcher->v_index);
        xdb_free_header((void *)header);
        if (err != 0) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "failed to create vector index cached searcher: %s", db_path);
            xdb_free_vector_index((void *)ip2region_searcher->v_index);
            if(ngx_http_ip2region_is_absolute_path(db_name) != NGX_OK) {
                free(db_path);
            }
            return NGX_CONF_ERROR;
        }
    } else if (strcmp(cache_policy, "content") == 0) {
        ip2region_searcher->c_buffer = xdb_load_content_from_file(db_path);
        if (ip2region_searcher->c_buffer == NULL) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "failed to load xdb content: %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

  1. Restart the reload/start so both the file and vector index are read from the same, unchanged xdb.
  2. Ensure the file path is stable during deployment (atomic rename, not in-place overwrite).
  3. Verify the file is readable by the nginx worker user.
  4. Replace the xdb with a complete file of the matching version.
  5. As a fallback, use cache policy "file" which does not require a preloaded index.

Example fix

// before (bad deploy)
cp new.ip2region.xdb /data/ip2region.xdb   # while nginx loading
// after
mv /data/ip2region.xdb.new /data/ip2region.xdb  # atomic, then nginx -s reload
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/bash
# ensure the xdb is not mutated during (re)load and is worker-readable
f=/data/ip2region.xdb
lsof "$f" | grep -v nginx && echo "WARN: file open by other writers"
sudo -u www-data test -r "$f" && echo readable || echo "not readable by nginx user"

Prevention

When it happens

Trigger: xdb_new_with_vector_index returns != 0: the xdb file cannot be opened/read by the current user, the file changed between loading the index and creating the searcher, or the loaded vector index does not correspond to the file's version/layout.

Common situations: Deploying a new xdb over the old path mid-reload so the cached vector index no longer matches; permissions changed between steps; mixing an index from one xdb with a different file version.

Related errors


AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02). Data as JSON: /api/errors/01731ae6f6660764. Report an issue: GitHub.