crowdsecurity/crowdsec · error
error in %s: %w
Error message
error in %s: %w
What it means
loadConfig parses each notification yaml with NewPluginConfigList; if YAML parsing or validation fails (bad syntax, unknown fields, duplicate/invalid plugin config), the file path and error are wrapped as "error in %s: %w". The file opened fine but its contents are not a valid plugin notification config.
Source
Thrown at pkg/csplugin/broker.go:233
func (pb *PluginBroker) loadConfig(path string) error {
files, err := listFilesAtPath(path)
if err != nil {
return err
}
for _, configFilePath := range files {
if !strings.HasSuffix(configFilePath, ".yaml") && !strings.HasSuffix(configFilePath, ".yml") {
continue
}
fin, err := os.Open(configFilePath)
if err != nil {
return fmt.Errorf("while opening %s: %w", configFilePath, err)
}
pluginConfigs, err := NewPluginConfigList(fin)
if err != nil {
return fmt.Errorf("error in %s: %w", configFilePath, err)
}
for _, pluginConfig := range pluginConfigs {
if _, ok := pb.pluginConfigByName[pluginConfig.Name]; ok {
log.Warningf("notification '%s' is defined multiple times", pluginConfig.Name)
}
pb.pluginConfigByName[pluginConfig.Name] = pluginConfig
if !pb.profilesContainPlugin(pluginConfig.Name) {
continue
}
}
}
return pb.verifyPluginConfigsWithProfile()
}
// checks whether every notification in profile has its own config fileView on GitHub (pinned to 909b515798)
Solutions
- Validate the yaml with a linter (yamllint) or `cscli` startup to see the line number in the wrapped error.
- Ensure the file contains a valid PluginConfig structure (name, type, format) as expected by NewPluginConfigList.
- Move unrelated yaml files out of the notification_dir.
- Compare against a working example from the crowdsec hub (e.g. notifications/http.yaml).
Example fix
// before: invalid yaml (tab indentation) name: slack_default type: slack // after name: slack_default type: slack
Defensive patterns
Strategy: validation
Validate before calling
// lint every yaml before deploy yamllint /etc/crowdsec/notifications/*.yaml
Try / catch
if err := broker.Init(ctx, cfg); err != nil {
if strings.Contains(err.Error(), "error in ") {
// parse the wrapped path from the message, validate that file
}
return err
} Prevention
- Run yamllint (or a yaml.safe_load_all) as a deploy step for notification configs.
- Keep notification yaml files 2-space indented, never tabs.
- Copy from hub examples rather than writing configs from scratch.
When it happens
Trigger: PluginBroker.Init -> loadConfig -> NewPluginConfigList(fin) returns an error for one yaml file: invalid YAML syntax, wrong top-level structure, missing required keys like name/type/format.
Common situations: Hand-edited notification config with indentation mistakes; copy-pasting a config that is a single map instead of a list; typo in keys; a file in the notifications dir that is actually something else with a .yaml extension.
Related errors
- cannot parse VictoriaLogs acquisition configuration: %s
- %s: %w
- stash %d: %w
- path must start with /
- basic_auth is selected, but basic_auth is not provided
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/918a2df209630466.
Report an issue: GitHub.