crowdsecurity/crowdsec · error

binary for plugin %s not found

Error message

binary for plugin %s not found

What it means

verifyPluginBinaryWithProfile checks that every notification referenced in profiles has a running plugin client (binary spawned over gRPC) in notificationPluginByName. Config exists, but the binary itself was not found/registered, so loadPlugins aborts. It catches the case where notification configs exist but the executable plugin is missing or failed to launch.

Source

Thrown at pkg/csplugin/broker.go:271

	for _, profileCfg := range pb.profileConfigs {
		for _, pluginName := range profileCfg.Notifications {
			if _, ok := pb.pluginConfigByName[pluginName]; !ok {
				return fmt.Errorf("config file for plugin %s not found", pluginName)
			}

			pb.pluginsTypesToDispatch[pb.pluginConfigByName[pluginName].Type] = struct{}{}
		}
	}

	return nil
}

// check whether each plugin in profile has its own binary
func (pb *PluginBroker) verifyPluginBinaryWithProfile() error {
	for _, profileCfg := range pb.profileConfigs {
		for _, pluginName := range profileCfg.Notifications {
			if _, ok := pb.notificationPluginByName[pluginName]; !ok {
				return fmt.Errorf("binary for plugin %s not found", pluginName)
			}
		}
	}

	return nil
}

func (pb *PluginBroker) loadPlugins(ctx context.Context, path string) error {
	binaryPaths, err := listFilesAtPath(path)
	if err != nil {
		return err
	}

	for _, binaryPath := range binaryPaths {
		if err := pluginIsValid(binaryPath); err != nil {
			return err
		}

View on GitHub (pinned to 909b515798)

Solutions

  1. Verify the plugin binary exists in plugin_dir with matching name (name in yaml must match binary filename) and is executable.
  2. Install the plugin binary package for the notification you configured.
  3. Check the earlier log line for the configure/startup failure of that plugin.
  4. Fix plugin_dir in crowdsec.yaml to point to the directory containing the binaries.

Example fix

// before
notification_dir: /etc/crowdsec/notifications/
plugin_dir: /wrong/path/
// after
plugin_dir: /usr/local/lib/crowdsec/plugins/
Defensive patterns

Strategy: validation

Validate before calling

// before starting crowdsec
for _, n := range profileNotifications {
    if _, err := os.Stat(filepath.Join(pluginDir, n)); err != nil {
        log.Warnf("plugin binary for %s not found", n)
    }
}

Try / catch

if err := broker.Init(ctx, cfg); err != nil {
    if strings.Contains(err.Error(), "binary for plugin") {
        // extract name, install the matching plugin binary package
    }
    return err
}

Prevention

When it happens

Trigger: PluginBroker.Init -> loadPlugins after spawning plugin binaries: profile lists a plugin whose binary is absent from plugin_dir, not executable, or whose load/Configure step failed earlier leaving no client registered.

Common situations: Notification config installed from hub but the plugin binary package (e.g. crowdsec-plugin-slack) not installed; plugin_dir points to wrong path; binary lacks +x; plugin binary version mismatched with crowdsec.

Related errors


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