lionsoul2014/ip2region · critical

failed to determine xdb version from header: %s

Error message

failed to determine xdb version from header: %s

What it means

At nginx startup, ip2region reads the first bytes of the xdb file to detect its IP format version (IPv2/IPv3/IPv4 structure). xdb_version_from_header returned NULL, meaning the header bytes do not match any known xdb version layout, so the module cannot initialize a searcher. This is a nginx conf-time (NGX_CONF_ERROR) failure that aborts nginx startup.

Source

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

    }

    ip2region_searcher->v_index = NULL;
    ip2region_searcher->c_buffer = NULL;

    // 检查XDB文件的版本信息以确定IP类型
    xdb_header_t *header = xdb_load_header_from_file(db_path);
    if (header == NULL) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "failed to load xdb header from: %s", db_path);
        if(ngx_http_ip2region_is_absolute_path(db_name) != NGX_OK) {
            free(db_path);
        }
        return NGX_CONF_ERROR;
    }

    xdb_version_t *xdb_version = xdb_version_from_header(header);
    if (xdb_version == NULL) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "failed to determine xdb version from header: %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;
    }

    // 验证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;

View on GitHub (pinned to c1a1fc7d59)

Solutions

  1. Verify the file is a genuine, complete ip2region xdb: check `file ip2region.xdb` and size, and re-download from the official data release.
  2. Confirm the configured path in nginx.conf resolves to the intended file (no typos, correct root-relative resolution).
  3. Regenerate or re-export the xdb with a maker tool from the same ip2region project version.
  4. Check the file is not gzip/xz compressed; decompress it before use.
  5. Confirm read permissions so the header can actually be read fully.

Example fix

# before
ip2region_db_file /etc/nginx/data/ip2region.xdb.gz;
# after
gunzip /etc/nginx/data/ip2region.xdb.gz
ip2region_db_file /etc/nginx/data/ip2region.xdb;
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/bash
# run before pointing nginx at the xdb
f=/data/ip2region.xdb
[ -s "$f" ] || { echo "missing/empty xdb"; exit 1; }
[ $(stat -c%s "$f") -ge 256 ] || { echo "xdb too small (truncated?)"; exit 1; }
# a real xdb starts with its structured header; reject compressed/text files
file "$f" | grep -Eqi 'gzip|xz|zip|ASCII text' && { echo 'not a raw xdb'; exit 1; }
echo "xdb header looks loadable"

Prevention

When it happens

Trigger: The ip2region_db_file/ip2region_db_file_v6 directive points to a file whose header is corrupt, truncated (shorter than the header size), empty, or not an xdb file at all (e.g. a text file, HTML error page from a bad download, or a .xz/.gz archive that was not decompressed).

Common situations: Downloading the xdb with curl that saved an error page; an incomplete/ interrupted download; a file that was renamed but not the actual ip2region xdb; a corrupted copy on a mounted volume; using an old/different data format file.

Related errors


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