{"record":{"id":"2ab98de6b47deedc","repo":"crowdsecurity/crowdsec","slug":"plugin-broker-w","errorCode":null,"errorMessage":"plugin broker: %w","messagePattern":"plugin broker: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apiserver/apiserver.go","lineNumber":535,"sourceCode":"\n\treturn false\n}\n\nfunc (s *APIServer) InitPlugins(ctx context.Context, cConfig *csconfig.Config, pluginBroker *csplugin.PluginBroker) error {\n\tif hasPlugins(s.cfg.Profiles) {\n\t\tlog.Info(\"initiating plugin broker\")\n\t\t// On windows, the plugins are always run as medium-integrity processes, so we don't care about plugin_config\n\t\tif cConfig.PluginConfig == nil && runtime.GOOS != \"windows\" {\n\t\t\treturn errors.New(\"plugins are enabled, but the plugin_config section is missing in the configuration\")\n\t\t}\n\n\t\tif cConfig.ConfigPaths.PluginDir == \"\" {\n\t\t\treturn errors.New(\"plugins are enabled, but config_paths.plugin_dir is not defined\")\n\t\t}\n\n\t\terr := pluginBroker.Init(ctx, cConfig.PluginConfig, s.cfg.Profiles, cConfig.ConfigPaths)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"plugin broker: %w\", err)\n\t\t}\n\n\t\tlog.Info(\"initiated plugin broker\")\n\t\ts.AttachPluginBroker(pluginBroker)\n\t}\n\n\treturn nil\n}\n\nfunc (s *APIServer) InitController() error {\n\terr := s.controller.Init()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"controller init: %w\", err)\n\t}\n\n\tif s.cfg.TLS == nil {\n\t\treturn nil\n\t}","sourceCodeStart":517,"sourceCodeEnd":553,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/apiserver/apiserver.go#L517-L553","documentation":"InitPlugins wraps errors from pluginBroker.Init, which loads notification plugin binaries and their YAML configs from the plugin directory and builds notifications from profiles. The LAPI continues to serve but notifications will not work — InitPlugins returns the error to the caller.","triggerScenarios":"InitPlugins called with notifications enabled but config_paths.plugin_dir unset (separate errors.New case, same wrapper path), plugin binaries missing/non-executable, or plugin YAML config files malformed.","commonSituations":"Installed binary-only crowdsec without notification plugins; plugin_dir points to wrong path; a plugin config (e.g. /etc/crowdsec/notifications/http.yaml) has bad yaml or missing required keys.","solutions":["Check the wrapped cause for which plugin/config file failed.","Set config_paths.plugin_dir in config.yaml to the directory containing crowdsec-notification-* binaries.","Verify plugin binaries exist and are executable (ls -l on plugin_dir).","Validate the plugin YAML in /etc/crowdsec/notifications/ against the plugin's documented schema.","If notifications aren't wanted, disable them rather than leaving a broken plugin config."],"exampleFix":"// before (config.yaml)\nconfig_paths:\n  # plugin_dir not set\n// after\nconfig_paths:\n  plugin_dir: /usr/lib/crowdsec/plugins/","handlingStrategy":"validation","validationCode":"// before enabling notifications\nif cfg.PluginConfig != nil || len(cfg.Profiles) > 0 {\n    if cConfig.ConfigPaths.PluginDir == \"\" {\n        return fmt.Errorf(\"notifications configured but config_paths.plugin_dir is empty\")\n    }\n    if ents, _ := os.ReadDir(cConfig.ConfigPaths.PluginDir); len(ents) == 0 {\n        return fmt.Errorf(\"plugin_dir %s is empty\", cConfig.ConfigPaths.PluginDir)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := server.InitPlugins(cConfig, ctx); err != nil {\n    if strings.Contains(err.Error(), \"plugin broker\") {\n        log.Errorf(\"notification plugins failed: %v — LAPI will run without notifications\", err)\n    }\n    return err\n}","preventionTips":["Install the crowdsec-notification-* binaries alongside the server.","Keep plugin YAML configs minimal and validated against plugin docs.","Set plugin_dir explicitly in config management (Ansible/puppet).","Test one plugin config locally before enabling notifications fleet-wide."],"tags":["plugins","notifications","configuration"],"backgroundTag":"missing-required-config-field","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}