crowdsecurity/crowdsec · error

plugins are enabled, but config_paths.plugin_dir is not defi

Error message

plugins are enabled, but config_paths.plugin_dir is not defined

What it means

When profiles use plugins, the broker must know where plugin binaries live; that path comes from config_paths.plugin_dir. If the profiles reference plugins but plugin_dir is empty, InitPlugins cannot locate them and returns this error.

Source

Thrown at pkg/apiserver/apiserver.go:530

	for _, profile := range profiles {
		if len(profile.Notifications) != 0 {
			return true
		}
	}

	return false
}

func (s *APIServer) InitPlugins(ctx context.Context, cConfig *csconfig.Config, pluginBroker *csplugin.PluginBroker) error {
	if hasPlugins(s.cfg.Profiles) {
		log.Info("initiating plugin broker")
		// On windows, the plugins are always run as medium-integrity processes, so we don't care about plugin_config
		if cConfig.PluginConfig == nil && runtime.GOOS != "windows" {
			return errors.New("plugins are enabled, but the plugin_config section is missing in the configuration")
		}

		if cConfig.ConfigPaths.PluginDir == "" {
			return errors.New("plugins are enabled, but config_paths.plugin_dir is not defined")
		}

		err := pluginBroker.Init(ctx, cConfig.PluginConfig, s.cfg.Profiles, cConfig.ConfigPaths)
		if err != nil {
			return fmt.Errorf("plugin broker: %w", err)
		}

		log.Info("initiated plugin broker")
		s.AttachPluginBroker(pluginBroker)
	}

	return nil
}

func (s *APIServer) InitController() error {
	err := s.controller.Init()
	if err != nil {
		return fmt.Errorf("controller init: %w", err)

View on GitHub (pinned to 909b515798)

Solutions

  1. Set config_paths.plugin_dir in config.yaml (usually /usr/lib/crowdsec/plugins/).
  2. Fix typos so the key is exactly plugin_dir under config_paths.
  3. Remove notification plugins from profiles if plugins are not used.

Example fix

# before
config_paths:
  data_dir: /var/lib/crowdsec/data/
# after
config_paths:
  data_dir: /var/lib/crowdsec/data/
  plugin_dir: /usr/lib/crowdsec/plugins/
Defensive patterns

Strategy: validation

Validate before calling

if len(cfg.API.Server.Profiles) > 0 && cfg.ConfigPaths.PluginDir == "" {
    return errors.New("config_paths.plugin_dir required when profiles use plugins")
}

Try / catch

if err := server.InitPlugins(ctx, cfg, broker); err != nil {
    log.Fatalf("plugin init: %v", err)
}

Prevention

When it happens

Trigger: api.server.profiles contain notifications but config_paths.plugin_dir is unset, misspelled (e.g. plugin-dir), or the config_paths section was dropped from config.yaml.

Common situations: Minimal/hand-written configs, packaging mistakes where the default config_paths block was removed, path renamed in a config migration.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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