crowdsecurity/crowdsec · error

scope is %s but '%s' isn't a valid ip

Error message

scope is %s but '%s' isn't a valid ip

What it means

When building the event source in eventSources, if the bucket's scope type is an IP-based scope (e.g. 'ip' or 'ip_in_range'), the value of evt.Meta["source_ip"] must parse as an IP address via net.ParseIP. If it's present but malformed (e.g. a hostname or garbage), this error is returned. It means the parser produced a Meta[source_ip] value that isn't a valid IP while the scenario's scope demands one.

Source

Thrown at pkg/leakybucket/overflows.go:114

	}

	return srcs, nil
}

func eventSources(evt pipeline.Event, leaky *Leaky) (map[string]models.Source, error) {
	srcs := make(map[string]models.Source)

	src := models.Source{}

	switch leaky.Factory.Spec.ScopeType.Scope {
	case types.Range, types.Ip:
		v, ok := evt.Meta["source_ip"]
		if !ok {
			return srcs, fmt.Errorf("scope is %s but Meta[source_ip] doesn't exist", leaky.Factory.Spec.ScopeType.Scope)
		}

		if net.ParseIP(v) == nil {
			return srcs, fmt.Errorf("scope is %s but '%s' isn't a valid ip", leaky.Factory.Spec.ScopeType.Scope, v)
		}

		src.IP = v
		// not &leaky.Factory.Spec.ScopeType.Scope: the factory is shared by every
		// bucket of the scenario, and postoverflow statics write through this pointer
		src.Scope = new(string)
		*src.Scope = leaky.Factory.Spec.ScopeType.Scope

		if v, ok := evt.Enriched["ASNumber"]; ok {
			src.AsNumber = v
		} else if v, ok := evt.Enriched["ASNNumber"]; ok {
			src.AsNumber = v
		}

		if v, ok := evt.Enriched["IsoCode"]; ok {
			src.Cn = v
		}

View on GitHub (pinned to 909b515798)

Solutions

  1. Fix the parser so Meta["source_ip"] is set only with a syntactically valid IP (validate with net.ParseIP in the parser/expression).
  2. Check the log line feeding the event — a malformed source field is being parsed as source_ip.
  3. Change the scenario scope type if IP scoping doesn't fit this event source (e.g. use a non-IP scope).
  4. Strip IPv6 zone identifiers before assigning source_ip.

Example fix

// before (parser)
Meta: source_ip: evt.Parsed.source_host  # may be 'unknown'
// after
Meta: source_ip: evt.Parsed.source_ip | filter(net.ParseIP(evt.Parsed.source_ip) != nil) ? evt.Parsed.source_ip : ""
Defensive patterns

Strategy: validation

Validate before calling

ip := evt.Meta["source_ip"]
if net.ParseIP(ip) == nil {
	// don't feed this event to an ip-scoped scenario / fix the parser
}

Try / catch

srcs, err := leaky.SourceFromEvent(evt, leaky)
if err != nil && strings.Contains(err.Error(), "isn't a valid ip") {
	leaky.logger.Warnf("dropping event with bad source_ip: %v", err)
	return nil
}

Prevention

When it happens

Trigger: A scenario whose scope.type is 'ip'/'ip_in_range' is evaluated against an event whose parsed Meta["source_ip"] fails net.ParseIP (empty-ish garbage, 'unknown', 'host.example.com').

Common situations: A parser enrichment wrote a hostname instead of an IP into source_ip; logs where the source field is optional and parsed to a non-IP placeholder; misconfigured custom parser; IPv6 zone identifiers like 'fe80::1%eth0' which net.ParseIP rejects.

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/4d01f2ddf7d4eb50. Report an issue: GitHub.