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 file

View on GitHub (pinned to 909b515798)

Solutions

  1. Validate the yaml with a linter (yamllint) or `cscli` startup to see the line number in the wrapped error.
  2. Ensure the file contains a valid PluginConfig structure (name, type, format) as expected by NewPluginConfigList.
  3. Move unrelated yaml files out of the notification_dir.
  4. 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

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


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