{"record":{"id":"f0e2151e69415402","repo":"crowdsecurity/crowdsec","slug":"event-has-multiple-source-types-s-s","errorCode":null,"errorMessage":"event has multiple source types : %s != %s","messagePattern":"event has multiple source types : (.+?) != (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/leakybucket/overflows.go","lineNumber":287,"sourceCode":"\tsources := make(map[string]models.Source)\n\n\tlog.Debugf(\"Formatting (%s) - scope Info : scope_type:%s / scope_filter:%s\", leaky.Factory.Spec.Name, leaky.Factory.Spec.ScopeType.Scope, leaky.Factory.Spec.ScopeType.Filter)\n\n\tqEvents := queue.GetQueue()\n\tfor idx := range qEvents {\n\t\tsrcs, err := SourceFromEvent(qEvents[idx], leaky)\n\t\tif err != nil {\n\t\t\treturn nil, \"\", fmt.Errorf(\"while extracting scope from bucket %s: %w\", leaky.Factory.Spec.Name, err)\n\t\t}\n\n\t\tfor key, src := range srcs {\n\t\t\tif source_type == types.Undefined {\n\t\t\t\tsource_type = *src.Scope\n\t\t\t}\n\n\t\t\tif *src.Scope != source_type {\n\t\t\t\treturn nil, \"\",\n\t\t\t\t\tfmt.Errorf(\"event has multiple source types : %s != %s\", *src.Scope, source_type)\n\t\t\t}\n\n\t\t\tsources[key] = src\n\t\t}\n\t}\n\n\treturn sources, source_type, nil\n}\n\n// NewAlert will generate a RuntimeAlert and its APIAlert(s) from a bucket that overflowed\nfunc NewAlert(leaky *Leaky, queue *pipeline.Queue) (pipeline.RuntimeAlert, error) {\n\tvar runtimeAlert pipeline.RuntimeAlert\n\n\tleaky.logger.Tracef(\"Overflow (start: %s, end: %s)\", leaky.First_ts, leaky.Ovflw_ts)\n\t/*\n\t\tCraft the models.Alert that is going to be duplicated for each source\n\t*/\n\tstart_at, err := leaky.First_ts.MarshalText()","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/leakybucket/overflows.go#L269-L305","documentation":"During alert formatting, crowdsec requires every event in the overflow queue to share one source scope type (e.g. all Ip, all Range). When processing queued events, if a second source's Scope differs from the first one recorded, alertFormatSource refuses to build a mixed-type alert with this error. It is an internal consistency check: a single alert cannot represent events scoped to different source types.","triggerScenarios":"Bucket overflow where events in the same queue produce srcs whose *src.Scope values differ (e.g. some events yield types.Ip, others types.Range or types.Undefined) — typically when a scope filter returns differently-typed/empty values across events.","commonSituations":"Custom scope filters that return an empty string or non-string value for some events (which falls back to an undefined scope) while others resolve to an IP/Range; scenarios applied to heterogeneous acquisition sources.","solutions":["Check the scenario's scope filter for inputs that can be empty for some events and normalize them (e.g. fall back to evt.Parsed.source_ip)","Ensure parsers/enrichers populate the fields the scope filter uses for every acquisition source the scenario applies to","If the scenario is intentionally generic, split it so each log type has its own consistent scope","Capture a dump of the queued events (leaky.Factory.Spec.Debug=true) to see which event produced the divergent scope"],"exampleFix":"// before\nscope:\n  type: range\n  filter: evt.Enriched.target_ips\n// after (guarantee a non-empty string)\nscope:\n  type: range\n  filter: Get(evt.Enriched, 'target_ips', evt.Parsed.target_ip)","handlingStrategy":"validation","validationCode":"// Ensure scope filters yield a consistent, non-empty string for all events:\n// in the expression: Get(field, fallback) — never a bare optional field","typeGuard":"// Expression-level guard:\n// val := Get(evt.Enriched, 'target_ips', evt.Parsed.target_ip); val != ''","tryCatchPattern":"// If generating alerts yourself:\nalert, _, err := alertFormatSource(leaky, queue)\nif err != nil && strings.Contains(err.Error(), \"multiple source types\") {\n    log.Warnf(\"mixed-scope overflow in %s; fix the scope filter\", leaky.Factory.Spec.Name)\n}","preventionTips":["Normalize scope filter output with a fallback for every event","Avoid applying one scenario to log types with different source semantics","Enable leaky.Factory.Spec.Debug to dump scopes of queued events when debugging","Split generic scenarios per acquisition type"],"tags":["crowdsec","alert","scope","consistency"],"backgroundTag":"incompatible-source-type","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}