lionsoul2014/ip2region · error

parse ip fail: %w

Error message

parse ip fail: %w

What it means

VersionFromIP determines whether an IP string is IPv4 or IPv6 by delegating to ParseIP. If the string cannot be parsed as either address family, the parse error is wrapped as 'parse ip fail'. It signals malformed or unsupported IP input, not an xdb/database problem.

Source

Thrown at binding/golang/xdb/version.go:71

			return 0
		},
	}
	IPv6 = &Version{
		Id:               IPv6VersionNo,
		Name:             "IPv6",
		Bytes:            16,
		SegmentIndexSize: 38, // 16 + 16 + 2 + 4,
		IPCompare: func(ip1, ip2 []byte) int {
			return bytes.Compare(ip1, ip2)
		},
	}
)

func VersionFromIP(ip string) (*Version, error) {
	r, err := ParseIP(ip)
	if err != nil {
		return IPvx, fmt.Errorf("parse ip fail: %w", err)
	}

	if len(r) == 4 {
		return IPv4, nil
	}

	return IPv6, nil
}

func VersionFromName(name string) (*Version, error) {
	switch strings.ToUpper(name) {
	case "V4", "IPV4":
		return IPv4, nil
	case "V6", "IPV6":
		return IPv6, nil
	default:
		return IPvx, fmt.Errorf("invalid version name `%s`", name)
	}

View on GitHub (pinned to c1a1fc7d59)

Solutions

  1. Validate/normalize the IP string before calling (trim spaces, strip brackets/port)
  2. Parse it yourself first with net.ParseIP (or netip.ParseAddr) to get a clearer stdlib error
  3. If the input may be a hostname, resolve it with net.LookupHost first and pass the resolved address
  4. For inputs with ports, split on the last ':' and pass only the host portion

Example fix

// before
v, err := xdb.VersionFromIP(req.Hostname) // parse ip fail
// after
ip := net.ParseIP(strings.TrimSpace(req.IP))
if ip == nil { return fmt.Errorf("not an IP: %q", req.IP) }
v, err := xdb.VersionFromIP(ip.String())
Defensive patterns

Strategy: validation

Validate before calling

func validIP(s string) bool { return net.ParseIP(strings.TrimSpace(s)) != nil }

Type guard

func isIPv4(s string) bool { ip := net.ParseIP(s); return ip != nil && ip.To4() != nil }
func isIPv6(s string) bool { ip := net.ParseIP(s); return ip != nil && ip.To4() == nil }

Try / catch

v, err := xdb.VersionFromIP(raw)
if err != nil {
    log.Printf("skipping unparseable IP %q: %v", raw, err)
    return defaultVersion
}

Prevention

When it happens

Trigger: Calling VersionFromIP with an empty string, a hostname instead of an IP literal, an IPv4 address with an out-of-range octet (e.g. 256.1.1.1), an IPv6 literal with invalid syntax, or a string containing a port or zone in an unparsable form.

Common situations: Passing user-supplied or log-extracted text without validation, reading IP columns from CSV that contain hostnames or 'unknown', accidentally passing 'ip:port' from a socket string.

Related errors


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