lionsoul2014/ip2region · error · InvalidConfigException

Both xdbFile and xdbPath is null

Error message

Both xdbFile and xdbPath is null

What it means

ConfigBuilder.build() requires a source xdb file. Neither setXdbFile nor setXdbPath was called (and no stream was provided), so there is nothing to open with RandomAccessFile. The builder validates this up front instead of failing later with a cryptic NPE or FileNotFoundException.

Source

Thrown at binding/java/src/main/java/org/lionsoul/ip2region/service/ConfigBuilder.java:115

            // 2, load the header
            final Header header = Searcher.loadHeaderFromBuffer(cBuffer);

            // 3, verify the xdb from the buffer
            Searcher.verify(header, cBuffer.length());

            // create the config without xdbFile and vIndex
            return new Config(cachePolicy, ipVersion, null, header, null, cBuffer, searchers, fairLock);
        }

        // load the header and the cache buffer
        final File xdbFile;
        if (this.xdbFile != null) {
            xdbFile = this.xdbFile;
        } else if (this.xdbPath != null) {
            xdbFile = new File(this.xdbPath);
        } else {
            throw new InvalidConfigException("Both xdbFile and xdbPath is null");
        }

        final RandomAccessFile raf = new RandomAccessFile(xdbFile, "r");

        // 1, verify the xdb
        Searcher.verify(raf);

        // 2, load the header
        final Header header = Searcher.loadHeader(raf);

        // 3, check and load the vector index buffer
        final byte[] vIndex = cachePolicy == Config.VIndexCache ? Searcher.loadVectorIndex(raf) : null;

        // 4, check and load the content buffer
        final LongByteArray cBuffer = cachePolicy == Config.BufferCache ? Searcher.loadContent(raf, cacheSliceBytes) : null;

        raf.close();
        return new Config(cachePolicy, ipVersion, xdbFile, header, vIndex, cBuffer, searchers, fairLock);

View on GitHub (pinned to c1a1fc7d59)

Solutions

  1. Call builder.setXdbPath("/path/to/ip2region.xdb") or builder.setXdbFile(new File(...)) before asV4()/asV6()
  2. Check that your configuration source (properties/env) actually supplies the xdb path and that it is not null/empty
  3. If you intended stream-based init, call setXdbInputStream with cachePolicy=Config.BufferCache instead

Example fix

// before
Ip2Region region = new ConfigBuilder().asV4();
// after
Ip2Region region = new ConfigBuilder()
    .setXdbPath("./data/ip2region.xdb")
    .asV4();
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(config.getXdbFile(), "xdbFile must be set");
Objects.requireNonNull(config.getXdbPath(), "xdbPath must be set");
if (config.getXdbFile() == null && config.getXdbPath() == null) {
    throw new IllegalStateException("provide xdbFile or xdbPath before building");
}

Try / catch

try {
    ip2Region = new ConfigBuilder().setXdbPath(xdbPath).asV4();
} catch (InvalidConfigException | IOException e) {
    log.error("xdb source missing or unreadable", e);
}

Prevention

When it happens

Trigger: Creating a new ConfigBuilder and calling asV4()/asV6() without ever invoking setXdbFile(File) or setXdbPath(String), or invoking them with null arguments.

Common situations: Building the searcher programmatically from config where the xdb path property was missing/empty; forgetting the builder step when copying sample initialization code.

Related errors


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