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

  1. Check the directory exists and is readable: `ls -la /etc/crowdsec/notifications/`; create it if missing.
  2. Run `yamllint /etc/crowdsec/notifications/*.yaml` and fix the syntax/schema error in the offending file (the wrapped error names it).
  3. Validate the plugin config structure against the stock example for that plugin type (email.yaml, http.yaml, slack.yaml).
  4. Fix file permissions so the crowdsec user can read the notification configs: `chown -R crowdsec:crowdsec /etc/crowdsec/notifications`.
  5. 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

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


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