crowdsecurity/crowdsec · error

invalid ip address '%s'

Error message

invalid ip address '%s'

What it means

Addr2Ints parses non-CIDR input with net.ParseIP; if it returns nil the string is neither a valid IPv4 nor IPv6 address, producing "invalid ip address '%s'". This is the plain-address branch used by NewRange and range tests. No underlying net error exists because ParseIP only signals failure by returning nil.

Source

Thrown at pkg/types/ip.go:49

		ip[1]|^n.Mask[1],
		ip[2]|^n.Mask[2],
		ip[3]|^n.Mask[3])
}

/*returns a range for any ip or range*/
func Addr2Ints(anyIP string) (int, int64, int64, int64, int64, error) {
	if strings.Contains(anyIP, "/") {
		_, net, err := net.ParseCIDR(anyIP)
		if err != nil {
			return -1, 0, 0, 0, 0, fmt.Errorf("invalid ip range '%s': %w", anyIP, err)
		}

		return Range2Ints(*net)
	}

	ip := net.ParseIP(anyIP)
	if ip == nil {
		return -1, 0, 0, 0, 0, fmt.Errorf("invalid ip address '%s'", anyIP)
	}

	sz, start, end, err := IP2Ints(ip)
	if err != nil {
		return -1, 0, 0, 0, 0, fmt.Errorf("invalid ip address '%s': %w", anyIP, err)
	}

	return sz, start, end, start, end, nil
}

/*size (16|4), nw_start, suffix_start, nw_end, suffix_end, error*/
func Range2Ints(network net.IPNet) (int, int64, int64, int64, int64, error) {
	szStart, nwStart, sfxStart, err := IP2Ints(network.IP)
	if err != nil {
		return -1, 0, 0, 0, 0, fmt.Errorf("converting first ip in range: %w", err)
	}

	lastAddr := LastAddress(network)

View on GitHub (pinned to 909b515798)

Solutions

  1. Ensure the input is a bare valid IP (strip ports, resolve hostnames with net.LookupIP first)
  2. Validate with net.ParseIP or netip.ParseAddr before calling Addr2Ints
  3. Check for empty or whitespace-only input coming from log parsing/splitting
  4. Remove leading zeros from IPv4 octets

Example fix

// before
host, port, _ := net.SplitHostPort(line)
ip := strings.TrimSpace(host) + ":80"   // port still attached
// after
ip, err := types.Addr2Ints(strings.TrimSpace(host))
Defensive patterns

Strategy: validation

Validate before calling

import "net/netip"
func validIP(s string) bool {
  _, err := netip.ParseAddr(strings.TrimSpace(s))
  return err == nil
}

Try / catch

r, err := types.NewRange(input)
if err != nil {
  if strings.Contains(err.Error(), "invalid ip address") && !strings.Contains(input, "/") {
    return fmt.Errorf("rejecting non-ip %q", input)
  }
  return err
}

Prevention

When it happens

Trigger: Calling Addr2Ints/NewRange with a slash-free string that net.ParseIP rejects — hostname, empty string, '1.2.3.4:80', '01.02.03.04' (leading zeros), truncated address.

Common situations: Passing a hostname instead of an IP; extracting the IP from a log line without stripping the port; leading-zero IPv4 octets (rejected by Go's ParseIP); empty field from a split that produced no data.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/5363159243e7ed7b. Report an issue: GitHub.