lionsoul2014/ip2region · error · XdbException

invalid structure version `${header.version}`

Error message

invalid structure version `${header.version}`

What it means

verify() reads the xdb header and only supports structure versions STRUCTURE_20 (4-byte runtime pointers) and STRUCTURE_30 (variable runtimePtrBytes). A header with any other version number means the file was not produced by a compatible ip2region writer or is corrupted, so an XdbException is thrown.

Source

Thrown at binding/java/src/main/java/org/lionsoul/ip2region/xdb/Searcher.java:377

    }

    // --- verify util function

    // Verify if the current Searcher could be used to search the specified xdb file.
    // Why do we need this check ?
    // The future features of the xdb impl may cause the current searcher not able to work properly.
    //
    // @Note: You Just need to check this ONCE when the service starts
    // Or use another process (eg, A command) to check once Just to confirm the suitability.
    public static void verify(Header header, long fileBytes) throws IOException, XdbException {
        // get the runtime ptr bytes
        int runtimePtrBytes = 0;
        if (header.version == STRUCTURE_20) {
            runtimePtrBytes = 4;
        } else if (header.version == STRUCTURE_30) {
            runtimePtrBytes = header.runtimePtrBytes;
        } else {
            throw new XdbException("invalid structure version `" + header.version + "`");
        }

        // 1, confirm the xdb file size
        // to ensure that the maximum file pointer does not overflow
        final long maxFilePtr = (1L << (runtimePtrBytes * 8)) - 1;
        if (fileBytes > maxFilePtr) {
            throw new XdbException("xdb file exceeds the maximum supported bytes: "+maxFilePtr+"");
        }
    }

    public static void verify(RandomAccessFile handle) throws IOException, XdbException {
        verify(loadHeader(handle), handle.length());
    }

    public static void verifyFromFile(File xdbFile) throws IOException, XdbException {
        final RandomAccessFile handle = new RandomAccessFile(xdbFile, "r");
        verify(handle);
        handle.close();

View on GitHub (pinned to c1a1fc7d59)

Solutions

  1. Regenerate the xdb with a compatible maker that emits structure 2.0 or 3.0
  2. Ensure you downloaded the official ip2region.xdb for this library version, not another IP DB format
  3. Re-download the file if the header may be corrupted, then run verify again

Example fix

// before
Searcher.verify(otherVendorIpDb); // unknown header version
// after
Searcher.verify(new File("ip2region.xdb")); // official 2.0/3.0 structure
Defensive patterns

Strategy: validation

Validate before calling

RandomAccessFile raf = new RandomAccessFile(xdbFile, "r");
try {
    Searcher.verify(raf); // throws XdbException on bad version
} finally { raf.close(); }

Try / catch

try {
    Searcher.verify(xdbFile);
} catch (XdbException e) {
    log.error("incompatible or corrupt xdb: {}", e.getMessage());
    throw new IllegalStateException("replace the xdb file", e);
}

Prevention

When it happens

Trigger: Running Searcher.verify / verify(handle) on an xdb generated by an incompatible/older tool, a random file passed as xdb, or a file whose header bytes are corrupted.

Common situations: Mixing xdb files from different projects/branches of ip2region; pointing the searcher at a placeholder or wrong-format IP database; bit rot in stored assets.

Related errors


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