crowdsecurity/crowdsec · error · InvalidFilter

unknown ip size %d: %w

Error message

unknown ip size %d: %w

What it means

decisionIPFilter only knows how to apply filters for 4-byte (IPv4), 16-byte (IPv6) or empty (0) ranges; any other netip.Addr byte-length raises this error wrapped with the InvalidFilter sentinel. It signals an impossible/unsupported range size from malformed address data.

Source

Thrown at pkg/database/decisionfilter.go:193

				// decision.end_ip == query.end_ip
				decision.EndIPEQ(rng.End.Addr),
				// decision.end_suffix <= query.end_suffix
				decision.EndSuffixLTE(rng.End.Sfx),
			),
		),
	)), nil
}

func decisionIPFilter(decisions *ent.DecisionQuery, contains bool, rng csnet.Range) (*ent.DecisionQuery, error) {
	switch rng.Size() {
	case 4:
		return decisionIPv4Filter(decisions, contains, rng)
	case 16:
		return decisionIPv6Filter(decisions, contains, rng)
	case 0:
		return decisions, nil
	default:
		return nil, fmt.Errorf("unknown ip size %d: %w", rng.Size(), InvalidFilter)
	}
}

func decisionPredicatesFromStr(s string, predicateFunc func(string) predicate.Decision) []predicate.Decision {
	words := strings.Split(s, ",")
	predicates := make([]predicate.Decision, len(words))

	for i, word := range words {
		predicates[i] = predicateFunc(word)
	}

	return predicates
}

View on GitHub (pinned to 909b515798)

Solutions

  1. Ensure the range comes from csnet.NewRange or netip parsing, not hand-built addresses.
  2. Log rng.Size() and rng.String() to identify the offending value.
  3. If constructing ranges in code, validate the address family (Is4/Is6) before building the Range.
  4. Report upstream if a valid parsed range yields an unexpected size.

Example fix

// before
rng := csnet.Range(netip.PrefixFrom(netip.AddrFrom4([4]byte{1,2,3,4}), 0)) // malformed
// after
rng, err := csnet.NewRange("1.2.3.0/24")
if err != nil { return err }
Defensive patterns

Strategy: validation

Validate before calling

switch rng.Size() {
case 4, 16, 0:
    // ok, safe to pass
default:
    return fmt.Errorf("range %q has unsupported size %d", rng.String(), rng.Size())
}

Try / catch

q, err := decisionIPFilter(query, contains, rng)
if err != nil {
    if strings.Contains(err.Error(), "unknown ip size") {
        return fmt.Errorf("rebuild range from a parsed IP: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling applyDecisionFilter, ExpireDecisionsWithFilter, CountDecisionsByValue or GetActiveDecisionsTimeLeftByValue with a csnet.Range whose underlying address has a size other than 0/4/16 — practically only via corrupted or non-standard range data.

Common situations: Rare: manually constructed csnet.Range values in tests or plugins; memory-corrupted or non-standard Addr; upstream csnet changes producing unexpected sizes.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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