crowdsecurity/crowdsec · error

format alerts for notification: %w

Error message

format alerts for notification: %w

What it means

pushNotificationsToPlugin renders the alert batch with the plugin's configured `format` template via FormatAlerts before dispatch; a template rendering failure is wrapped as "format alerts for notification: %w". The plugin config's format template is invalid for the alert payload (bad template syntax or unsupported field access).

Source

Thrown at pkg/csplugin/broker.go:417

	)

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

	if len(alerts) == 0 {
		return nil
	}

	pluginCfg := pb.pluginConfigByName[pluginName]

	message, err := FormatAlerts(pluginCfg.Format, alerts)
	if err != nil {
		return fmt.Errorf("format alerts for notification: %w", err)
	}

	// make sure we have a default or custom backoff
	pb.ensureBackoff()

	err = retryWithBackoff(ctx, pluginCfg, logger, func(ctx context.Context) error {
		return pb.tryNotify(ctx, pluginName, message)
	}, pb.newBackoff)
	if err != nil {
		if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
			logger.Warn("delivery canceled during shutdown")
		} else {
			logger.Errorf("delivery failed after retries: %v", err)
		}
	}

	return err
}

View on GitHub (pinned to 909b515798)

Solutions

  1. Test the template independently (e.g. cscli or a small Go program using text/template) to get the exact failing expression.
  2. Fix the `format:` in the notification yaml: check field names against the alert struct and valid expr helpers.
  3. Start from a known-good default template for the plugin type and re-apply changes incrementally.
  4. Escape braces/literals correctly — stray {{ or }} breaks parsing.

Example fix

// before: unknown field in template
format: '{{ .Alerts }}'
// after
format: '{{ range .Alerts }}{{ .EventCapacity }}{{ end }}'
Defensive patterns

Strategy: validation

Validate before calling

// dry-run the template with a sample alert before deploying
if _, err := FormatAlerts(cfg.Format, sampleAlerts); err != nil {
    return fmt.Errorf("bad format template: %w", err)
}

Try / catch

message, err := FormatAlerts(pluginCfg.Format, alerts)
if err != nil {
    log.Errorf("invalid format for %s: %v; falling back to default", pluginName, err)
    message, err = FormatAlerts(DefaultFormat, alerts)
}

Prevention

When it happens

Trigger: pushNotificationsToPlugin (from Run dispatch or anonymous goroutine): FormatAlerts(pluginCfg.Format, alerts) errors — malformed Go template syntax, calling a function not in expr helpers, or referencing fields not present in the alert/models.

Common situations: Custom `format:` in a notification yaml with template typos ({{ .NewAlerts }} vs actual key), bad pipeline/expr syntax, copy-pasted template from an incompatible notification plugin version.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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