lionsoul2014/ip2region · error · Error
invalid bytes ip with length not 4 or 16
Error message
invalid bytes ip with length not 4 or 16
What it means
After confirming the input is a Buffer, ipToString dispatches on length: 4 bytes are rendered as IPv4 and 16 bytes as IPv6. Any other length means the data is not a valid binary IP, so the library throws rather than guessing a format.
Source
Thrown at binding/javascript/util.js:228
_.push('');
}
}
return _.join(':');
}
// bytes ip to humen-readable string ip
export function ipToString(ipBytes, compress) {
if (!Buffer.isBuffer(ipBytes)) {
throw new Error('invalid bytes ip, not a Buffer');
}
if (ipBytes.length == 4) {
return _ipv4_to_string(ipBytes, compress);
} else if (ipBytes.length == 16) {
return _ipv6_to_string(ipBytes, compress);
} else {
throw new Error('invalid bytes ip with length not 4 or 16');
}
}
export function ipBytesString(ipBytes) {
if (!Buffer.isBuffer(ipBytes)) {
throw new Error('invalid bytes ip, not a Buffer');
}
let ps = [];
for (var i = 0; i < ipBytes.length; i++) {
ps.push(ipBytes[i] & 0xFF);
}
return ps.join('.');
}
// compare two byte ips
// ip2 = buff[offset:ip1.length]View on GitHub (pinned to c1a1fc7d59)
Solutions
- Verify the slice length: use exactly 4 bytes for IPv4 and 16 bytes for IPv6 (Buffer.subarray(start, start+4|16)).
- Store/emit IPs in a fixed width matching their family; pad IPv4 into a 16-byte IPv4-mapped form if you want a single format.
- Log ipBytes.length at the call site to find which producer emits the bad length.
- Validate inputs with a length check before calling.
Example fix
// before const ip = ipToString(buf.subarray(off)); // wrong length // after const len = version === 4 ? 4 : 16; const ip = ipToString(buf.subarray(off, off + len));
Defensive patterns
Strategy: validation
Validate before calling
function assertIpLength(b) {
if (!Buffer.isBuffer(b) || (b.length !== 4 && b.length !== 16))
throw new Error(`ip bytes must be 4 or 16 long, got ${b && b.length}`);
}
assertIpLength(ipBytes); Type guard
function isWellSizedIp(b) { return Buffer.isBuffer(b) && (b.length === 4 || b.length === 16); } Try / catch
try {
return ipToString(bytes);
} catch (e) {
if (String(e.message).includes('length not 4 or 16')) {
throw new Error(`bad ip slice near offset ${off}: length=${bytes.length}`);
}
throw e;
} Prevention
- Slice with explicit end offsets (subarray(off, off+4|16)), never a bare start offset.
- Store the IP family alongside the bytes and derive length from it.
- Unit-test your offset arithmetic against known IPv4 and IPv6 records.
When it happens
Trigger: Passing a Buffer of wrong size: a truncated slice (e.g. bytes.slice(0, 8)), a 6-byte MAC-style buffer, a zero-length buffer from an empty read, or an IPv4-mapped address stored as 12 bytes.
Common situations: Manual offset arithmetic over the xdb content buffer slicing the wrong byte count; mixing IPv4 and IPv6 records and assuming one size; corrupt or partially written custom data blobs.
Related errors
- invalid bytes ip, not a Buffer
- ip verison not match: xdb file ${xdbFile.getAbsolutePath()}
- incomplete read (${rBytes} read, ${header.HeaderInfoLength}
- incomplete read (${rBytes} read, ${vBytes} expected)
- incomplete read (${rBytes} read, ${stats.size} expected)
AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02).
Data as JSON: /api/errors/4e411b125df662ba.
Report an issue: GitHub.