crowdsecurity/crowdsec · error

missing required field 'type'

Error message

missing required field 'type'

What it means

PluginBroker's notification plugin config implements UnmarshalYAML, which requires every plugin entry to declare a 'type' field identifying the plugin kind. An empty type cannot be mapped to a plugin binary/runner, so unmarshaling the YAML fails immediately.

Source

Thrown at pkg/csplugin/broker.go:80

	MaxRetry       uint          `yaml:"max_retry,omitempty"`
	TimeOut        time.Duration `yaml:"timeout,omitempty"`

	Format string `yaml:"format,omitempty"` // specific to notification plugins

	Config map[string]any `yaml:",inline"` // to keep the plugin-specific config
}

// UnmarshalYAML implements yaml.Unmarshaler.
func (pc *PluginConfig) UnmarshalYAML(unmarshal func(any) error) error {
	type raw PluginConfig
	aux := raw{}

	if err := unmarshal(&aux); err != nil {
		return err
	}

	if aux.Type == "" {
		return errors.New("missing required field 'type'")
	}

	if aux.TimeOut == 0 {
		aux.TimeOut = time.Second * 5
	}

	*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)

View on GitHub (pinned to 909b515798)

Solutions

  1. Add 'type: <plugin_name>' (matching the plugin binary name, e.g. type: http) to the plugin config entry
  2. Verify the type key is nested at the correct level of the plugin entry, not in a sibling mapping
  3. Check the plugin's documentation for its exact expected type value

Example fix

// before
slack:
  webhook_url: https://hooks.slack.com/...

// after
slack:
  type: slack
  webhook_url: https://hooks.slack.com/...
Defensive patterns

Strategy: validation

Validate before calling

for name, pc := range pluginConfigs {
    if pc.Type == "" {
        return fmt.Errorf("plugin %q is missing required 'type' field", name)
    }
}

Try / catch

if err := yaml.Unmarshal(raw, &pluginCfg); err != nil {
    if strings.Contains(err.Error(), "missing required field 'type'") {
        log.Fatalf("plugin entry needs a 'type:' key matching the plugin binary")
    }
    return err
}

Prevention

When it happens

Trigger: A notification plugin entry in config.yaml (e.g. under the plugin configuration file) that omits 'type:', or spells it 'type :""' / uses a wrong key like 'kind:'.

Common situations: Copying a plugin example and deleting the type line; indented YAML under the wrong parent so type isn't decoded into the aux struct; writing a plugin config from a script that emits empty type.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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