lionsoul2014/ip2region · error
parse ip %s: %w
Error message
parse ip %s: %w
What it means
Go xdb.Searcher.Search: the string ip failed ParseIP, so it is neither a valid IPv4 nor IPv6 literal; the input string and the underlying parse error are wrapped together.
Source
Thrown at binding/golang/xdb/searcher.go:118
// IPVersion return the ip version
func (s *Searcher) IPVersion() *Version {
return s.version
}
// GetIOCount return the global io count for the last search
func (s *Searcher) GetIOCount() int {
return s.ioCount
}
// Search the region for the specified string or bytes ip address
func (s *Searcher) Search(ip any) (string, error) {
var err error
var ipBytes []byte
switch v := ip.(type) {
case string:
ipBytes, err = ParseIP(v)
if err != nil {
return "", fmt.Errorf("parse ip %s: %w", v, err)
}
case []byte:
ipBytes = v
default:
return "", fmt.Errorf("invalid ip value type %s", v)
}
// ip version check
if len(ipBytes) != s.version.Bytes {
return "", fmt.Errorf("invalid ip address(%s expected)", s.version.Name)
}
// reset the global ioCount
s.ioCount = 0
// locate the segment index block based on the vector index
var il0, il1 = int(ipBytes[0]), int(ipBytes[1])
var idx = il0*VectorIndexCols*VectorIndexSize + il1*VectorIndexSizeView on GitHub (pinned to c1a1fc7d59)
Solutions
- Validate the IP string with net.ParseIP (or xdb.IsIPv4/IsIPv6) before calling Search.
- Trim whitespace and strip any port suffix from the input string.
- Check that the string family (v4 vs v6) matches the xdb file version the searcher was loaded for.
- Handle the wrapped error by inspecting err.Unwrap() to distinguish parse failure from read failure.
Example fix
// before
region, err := searcher.Search(ctx, rawIP)
// after
if net.ParseIP(strings.TrimSpace(rawIP)) == nil {
return "", fmt.Errorf("not an IP: %q", rawIP)
}
region, err := searcher.Search(ctx, strings.TrimSpace(rawIP)) Defensive patterns
Strategy: validation
Validate before calling
ip := net.ParseIP(strings.TrimSpace(raw))
if ip == nil {
return fmt.Errorf("invalid ip string: %q", raw)
} Type guard
func isIPString(s string) bool { return net.ParseIP(strings.TrimSpace(s)) != nil } Try / catch
region, err := searcher.Search(ctx, raw)
if err != nil {
var parseErr error
if errors.Unwrap(err) != nil { parseErr = errors.Unwrap(err) }
return fmt.Errorf("lookup failed: %w (input=%q)", parseErr, raw)
} Prevention
- Trim and normalize IP strings from logs/user input before lookup.
- Skip placeholders like "-" or "unknown" without calling Search.
- Use net.ParseIP as a cheap pre-check.
- Keep the raw value in your wrapped error for debugging.
When it happens
Trigger: Calling searcher.Search(ctx, "999.1.2.3") or any malformed string like "abc", "1.2.3", or an IPv6 literal with bad syntax; also passing a v4-only string to a v6 searcher if ParseIP rejects it.
Common situations: Log-line IP fields containing placeholders like "-" or "unknown"; user-supplied input not validated before lookup; trailing whitespace or port appended ("1.2.3.4:8080").
Related errors
- invalid input buffer
- invalid ip value type %s
- invalid ip address(%s expected)
- read vector index block at %d: %w
- read segment index at %d: %w
AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02).
Data as JSON: /api/errors/9dcbf3c85935e810.
Report an issue: GitHub.