crowdsecurity/crowdsec · error

invalid type for ip : %T

Error message

invalid type for ip : %T

What it means

The `cti` expr helper function (CrowdsecCTI) expects its first parameter to be a string containing an IP address. If the caller passes a non-string value (e.g. net.IP, a number, or nil), the function returns this 'invalid type for ip : %T' error instead of performing the CTI lookup.

Source

Thrown at pkg/cticlient/ctiexpr/expr.go:93

)

func CrowdsecCTIInitCache(size int, ttl time.Duration) {
	CTICache = gcache.New(size).LRU().Build()
	CacheExpiration = ttl
}

// func CrowdsecCTI(ip string) (*cticlient.SmokeItem, error) {
func CrowdsecCTI(params ...any) (any, error) {
	var ip string

	if !CTIApiEnabled {
		return &cticlient.SmokeItem{}, cticlient.ErrDisabled
	}

	var ok bool

	if ip, ok = params[0].(string); !ok {
		return &cticlient.SmokeItem{}, fmt.Errorf("invalid type for ip : %T", params[0])
	}

	if val, err := CTICache.Get(ip); err == nil && val != nil {
		ctiClient.Logger.Debugf("cti cache fetch for %s", ip)

		ret, ok := val.(*cticlient.SmokeItem)
		if ok {
			return ret, nil
		}

		ctiClient.Logger.Warningf("CrowdsecCTI: invalid type in cache, removing")

		CTICache.Remove(ip)
	}

	if !CTIBackOffUntil.IsZero() && time.Now().Before(CTIBackOffUntil) {
		// ctiClient.Logger.Warningf("Crowdsec CTI client is in backoff mode, ending in %s", time.Until(CTIBackOffUntil))
		return &cticlient.SmokeItem{}, cticlient.ErrLimit

View on GitHub (pinned to 909b515798)

Solutions

  1. Convert the argument to a string: use Alert.Source.GetIP() or a string-typed field.
  2. Guard against nil: `Alert.Source.IP != nil && cti(...)`. Prefer string casts in expr.
  3. Check the wrapped inner error shows the actual %T to identify what type you passed.

Example fix

// before (expr)
cti(Alert.Source.IP)
// after
cti(Alert.Source.GetIP())
Defensive patterns

Strategy: type-guard

Validate before calling

ipStr, ok := rawIp.(string)
if !ok {
    return fmt.Errorf("cti() requires a string IP, got %T", rawIp)
}

Type guard

func isString(v interface{}) bool { _, ok := v.(string); return ok }

Try / catch

res, err := cti(Alert.Source.GetIP())
if err != nil {
    log.Warnf("cti lookup skipped: %v", err)
}

Prevention

When it happens

Trigger: Using cti(...) in an expression (whitelist, filter, enrichment) where the argument is not a plain string: passing Alert.Source.IP typed as net.IP, a parsed value, or nil rather than a string.

Common situations: Writing expr like `cti(Alert.Source.IP)` where the field resolves to a non-string type; passing a variable that is nil; constructing expressions programmatically with wrong parameter types.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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