crowdsecurity/crowdsec · error

plugin : notifier not registered

Error message

plugin %q: notifier not registered

What it means

tryNotify checks that a registered gRPC client exists in notificationPluginByName before calling Notify; if missing or nil it returns "plugin %q: notifier not registered". Config exists, but the plugin binary client was never successfully registered (spawn/Configure failed) or was lost.

Solutions

  1. Search startup logs for the registration failure of this plugin (e.g. 'while configuring').
  2. Restart crowdsec so loadPlugins re-spawns the plugin binary.
  3. Verify the binary exists, is executable, and matches crowdsec's protobuf API.
  4. Test the plugin manually: run it standalone and check it starts and accepts config.

Example fix

// before: plugin binary removed after install
$ ls plugins/  # notification-email missing
// after
make build && cp ./plugins/notification-email /usr/local/lib/crowdsec/plugins/ && systemctl restart crowdsec
Defensive patterns

Strategy: type-guard

Validate before calling

plugin, ok := broker.notificationPluginByName[name]
if !ok || plugin == nil { /* skip or reschedule */ }

Type guard

func isRegistered(m map[string]protobufs.PluginClient, name string) bool {
    p, ok := m[name]
    return ok && p != nil
}

Try / catch

if !isRegistered(broker.notificationPluginByName, name) {
    log.Warnf("notifier %s not registered; will retry on next alert", name)
    return nil
}

Prevention

When it happens

Trigger: tryNotify with a plugin that has a config but no registered client: binary failed to start earlier, Configure failed (805) but processing continued, or plugin process died and the client was removed.

Common situations: Plugin binary crashed after startup; startup error for this plugin was logged and crowdsec continued without it; plugin_dir changed between runs; partial Init failure tolerated in a caller that proceeds anyway.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at pkg/csplugin/broker.go:390

	return raw.(protobufs.NotifierServer), nil
}

func (pb *PluginBroker) tryNotify(ctx context.Context, pluginName, message string) error {
	// config guard
	pc, ok := pb.pluginConfigByName[pluginName]
	if !ok {
		return fmt.Errorf("plugin %q: config not found", pluginName)
	}

	timeout := pc.TimeOut
	ctxTimeout, cancel := context.WithTimeout(ctx, timeout)

	defer cancel()

	// plugin guard
	plugin, ok := pb.notificationPluginByName[pluginName]
	if !ok || plugin == nil {
		return fmt.Errorf("plugin %q: notifier not registered", pluginName)
	}

	_, err := plugin.Notify(
		ctxTimeout,
		&protobufs.Notification{
			Text: message,
			Name: pluginName,
		},
	)

	return err
}

func (pb *PluginBroker) pushNotificationsToPlugin(ctx context.Context, pluginName string, alerts []*models.Alert) error {
	logger := log.WithField("plugin", pluginName)

	logger.Debugf("pushing %d alerts to plugin", len(alerts))

View on GitHub (pinned to 909b515798)