lionsoul2014/ip2region · error · XdbException

xdb file exceeds the maximum supported bytes: ${maxFilePtr}

Error message

xdb file exceeds the maximum supported bytes: ${maxFilePtr}

What it means

For structure 2.0 the runtime pointer is 4 bytes, capping addressable file size at 2^32-1 bytes (or the header-declared runtimePtrBytes for 3.0). verify() rejects xdb files larger than this maximum because index pointers could not address the whole file, throwing XdbException.

Source

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

    //
    // @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();
    }

    public static void verifyFromFile(String xdbPath) throws IOException, XdbException {
        verifyFromFile(new File(xdbPath));
    }

}

View on GitHub (pinned to c1a1fc7d59)

Solutions

  1. Regenerate the xdb with STRUCTURE_30 (which supports larger runtime pointer bytes) via a 3.0-capable maker
  2. Split the dataset into multiple xdb files each under the size limit
  3. Confirm the file is actually the intended xdb and not a mistakenly large file

Example fix

// before
maker with STRUCTURE_20 producing 5GB xdb -> verify fails
// after
use structure 3.0 maker (STRUCTURE_30) so runtimePtrBytes=8 covers large files
Defensive patterns

Strategy: validation

Validate before calling

RandomAccessFile raf = new RandomAccessFile(xdbFile, "r");
Header h = Searcher.loadHeader(raf);
int ptrBytes = (h.version == 2) ? 4 : h.runtimePtrBytes;
long maxFilePtr = (1L << (ptrBytes * 8)) - 1;
if (new File(xdbFile).length() > maxFilePtr) throw new IllegalStateException("xdb too large for structure " + h.version);

Try / catch

try {
    Searcher.verify(xdbFile);
} catch (XdbException e) {
    log.error("xdb exceeds pointer capacity; regenerate with structure 3.0", e);
}

Prevention

When it happens

Trigger: Calling Searcher.verify on an xdb whose size exceeds (1L << (runtimePtrBytes*8)) - 1 — practically, a >4GB xdb under STRUCTURE_20.

Common situations: Generating an enormous merged IP database with an old 2.0 maker; concatenating xdb files; mistakenly verifying an unrelated huge data file.

Related errors


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