crowdsecurity/crowdsec · error
loading config: %w
Error message
loading config: %w
What it means
PluginBroker.Init sets up the notification plugin system and first loads plugin configurations from the notifications yaml directory (loadConfig). Any error reading/parsing that directory (missing dir, unreadable files, invalid yaml configs) is wrapped as 'loading config'. Without it, no notification plugins can be dispatched and LAPI startup aborts.
Source
Thrown at pkg/csplugin/broker.go:104
*pc = PluginConfig(aux)
return nil
}
type PluginConfigList []PluginConfig
func (pb *PluginBroker) Init(ctx context.Context, pluginCfg *csconfig.PluginCfg, profileConfigs []*csconfig.ProfileCfg, configPaths *csconfig.ConfigurationPaths) error {
pb.PluginChannel = make(chan models.ProfileAlert)
pb.notificationPluginByName = make(map[string]protobufs.NotifierServer)
pb.pluginMap = make(map[string]plugin.Plugin)
pb.pluginConfigByName = make(map[string]PluginConfig)
pb.alertsByPluginName = make(map[string][]*models.Alert)
pb.profileConfigs = profileConfigs
pb.pluginProcConfig = pluginCfg
pb.pluginsTypesToDispatch = make(map[string]struct{})
if err := pb.loadConfig(configPaths.NotificationDir); err != nil {
return fmt.Errorf("loading config: %w", err)
}
if err := pb.loadPlugins(ctx, configPaths.PluginDir); err != nil {
return fmt.Errorf("loading plugin: %w", err)
}
pb.watcher = PluginWatcher{}
pb.watcher.Init(pb.pluginConfigByName, pb.alertsByPluginName)
return nil
}
func (pb *PluginBroker) ensureBackoff() backoffFactory {
if pb.newBackoff == nil {
pb.newBackoff = defaultBackoffFactory
}
return pb.newBackoff
}View on GitHub (pinned to 909b515798)
Solutions
- Check the directory exists and is readable: `ls -la /etc/crowdsec/notifications/`; create it if missing.
- Run `yamllint /etc/crowdsec/notifications/*.yaml` and fix the syntax/schema error in the offending file (the wrapped error names it).
- Validate the plugin config structure against the stock example for that plugin type (email.yaml, http.yaml, slack.yaml).
- Fix file permissions so the crowdsec user can read the notification configs: `chown -R crowdsec:crowdsec /etc/crowdsec/notifications`.
- Temporarily move suspect yaml files out of the directory and restart to isolate the broken one.
Example fix
// before (notifications/email.yaml, missing required 'format') type: email name: email_default // after type: email name: email_default format: >- Crowdsec alert ...
Defensive patterns
Strategy: validation
Validate before calling
dir := configPaths.NotificationDir
info, err := os.Stat(dir)
if err != nil {
return fmt.Errorf("notification dir %s missing: %w", dir, err)
}
if !info.IsDir() { return fmt.Errorf("%s is not a directory", dir) }
files, _ := os.ReadDir(dir)
for _, f := range files {
if strings.HasSuffix(f.Name(), ".yaml") || strings.HasSuffix(f.Name(), ".yml") {
if _, err := os.ReadFile(filepath.Join(dir, f.Name())); err != nil {
return fmt.Errorf("unreadable notification config %s: %w", f.Name(), err)
}
}
} Try / catch
if err := broker.Init(ctx, configPaths, pluginCfg, profileConfigs); err != nil {
if strings.Contains(err.Error(), "loading config") {
// fix or remove the broken yaml in notification_dir, then retry
}
return err
} Prevention
- Ensure /etc/crowdsec/notifications exists with crowdsec-readable permissions after installs.
- Validate every notification yaml (yamllint + schema check against the plugin's example).
- Re-validate notification configs after crowdsec upgrades as plugin config schemas evolve.
- Keep plugin configs owned by crowdsec:crowdsec with mode 640/644.
When it happens
Trigger: config_paths.notification_dir (default /etc/crowdsec/notifications/) is missing, unreadable, or contains yaml files whose plugin configs fail to parse (wrong structure for http/email/slack/splunk plugins).
Common situations: Fresh installs where the notifications dir wasn't created; hand-written notification yamls with malformed fields; packages upgraded such that old plugin config keys no longer match; permission issues after manual edits with root-only files.
Understand the failure class
Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.
Related errors
- plugin %q: config not found
- while getting process attributes: both plugin user and group
- plugin broker: %w
- loading plugin: %w
- config file for plugin %s not found
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/52f788a748d4b4f3.
Report an issue: GitHub.