lionsoul2014/ip2region · error · InetAddressException
invalid ip address (${version.name} expected)
Error message
invalid ip address (${version.name} expected) What it means
Xdb Searcher instances are version-bound: a V4 searcher only accepts byte[4] IPs and a V6 searcher only byte[16]. The public search(byte[]) checks ip.length against version.bytes and throws InetAddressException when the IP version does not match the searcher's xdb version.
Source
Thrown at binding/java/src/main/java/org/lionsoul/ip2region/xdb/Searcher.java:115
}
}
public Version getIPVersion() {
return version;
}
public int getIOCount() {
return ioCount;
}
public String search(String ipStr) throws Exception {
return search(Util.parseIP(ipStr));
}
public String search(byte[] ip) throws IOException, InetAddressException {
// ip version check
if (ip.length != version.bytes) {
throw new InetAddressException("invalid ip address ("+version.name+" expected)");
}
// reset the global counter
this.ioCount = 0;
// locate the segment index block based on the vector index
long sPtr = 0, ePtr = 0;
int il0 = (int) (ip[0] & 0xFF);
int il1 = (int) (ip[1] & 0xFF);
int idx = il0 * VectorIndexCols * VectorIndexSize + il1 * VectorIndexSize;
// System.out.printf("il0: %d, il1: %d, idx: %d\n", il0, il1, idx);
if (vectorIndex != null) {
sPtr = LittleEndian.getUint32(vectorIndex, idx);
ePtr = LittleEndian.getUint32(vectorIndex, idx + 4);
} else if (contentBuff != null) {
sPtr = contentBuff.getUint32(HeaderInfoLength + idx);
ePtr = contentBuff.getUint32(HeaderInfoLength + idx + 4);
} else {View on GitHub (pinned to c1a1fc7d59)
Solutions
- Route the IP to the searcher matching its version: ip.length==4 -> v4 searcher, ip.length==16 -> v6 searcher
- Use Ip2Region.search(String) or a length check on the raw bytes to pick the correct searcher
- Create/keep both a V4 and a V6 searcher and dispatch on array length
Example fix
// before String r = v6Searcher.search(ipBytes); // ipBytes.length == 4 // after String r = (ipBytes.length == 4) ? v4Searcher.search(ipBytes) : v6Searcher.search(ipBytes);
Defensive patterns
Strategy: type-guard
Validate before calling
if (ip.length != expectedVersionBytes) {
throw new IllegalArgumentException("searcher version mismatch");
} Type guard
static boolean matchesSearcherVersion(byte[] ip, Version v) {
return ip != null && ip.length == v.bytes;
} Try / catch
try {
return searcher.search(ip);
} catch (InetAddressException e) {
log.warn("ip version mismatch for searcher", e);
return alternateSearcher(ip);
} Prevention
- Keep both v4 and v6 searchers and dispatch on ip.length
- Never share one Searcher across dual-stack traffic
- Name variables explicitly (v4Searcher/v6Searcher) to avoid wiring mistakes
When it happens
Trigger: Calling search on a searcher built via asV4() with a 16-byte IPv6 array, or via asV6() with a 4-byte IPv4 array.
Common situations: Dual-stack applications routing all incoming addresses through a single V4 searcher; using the wrong Ip2Region field (v4 vs v6) after a code refactor.
Related errors
- invalid byte ip address with length=${ipBytes.length}
- invalid structure version `${header.version}`
- invalid ip address `${ip}`
- invalid ip address `{}` ({} expected)
- ip verison not match: xdb file ${xdbFile.getAbsolutePath()}
AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02).
Data as JSON: /api/errors/73f8fbad18b5739c.
Report an issue: GitHub.