crowdsecurity/crowdsec · error

ErrInvalidMetricsLevel

ErrInvalidMetricsLevel

Error message

invalid metrics level

What it means

RegisterMetrics validates the configured metrics level string. Only 'full' and 'aggregated' (MetricsLevelFull / MetricsLevelAggregated; default 'full') are accepted; any other value makes RegisterMetrics return ErrInvalidMetricsLevel wrapped with the offending string.

Source

Thrown at pkg/metrics/metrics.go:20

import (
	"errors"
	"fmt"

	"github.com/prometheus/client_golang/prometheus"
)

type MetricsLevelConfig string

const (
	MetricsLevelNone       MetricsLevelConfig = "none"
	MetricsLevelAggregated MetricsLevelConfig = "aggregated"
	MetricsLevelFull       MetricsLevelConfig = "full"
	// MetricsLevelDefault is the default metrics level.
	MetricsLevelDefault MetricsLevelConfig = MetricsLevelFull
)

var ErrInvalidMetricsLevel = errors.New("invalid metrics level")

type AcquisitionMetricsLevel int

const (
	AcquisitionMetricsLevelNone       AcquisitionMetricsLevel       = iota // No metrics
	AcquisitionMetricsLevelAggregated                                      // Aggregated metrics
	AcquisitionMetricsLevelFull                                            // Full metrics
	AcquisitionMetricsLevelDefault    = AcquisitionMetricsLevelFull        // Default metrics level
)

func RegisterMetrics(metricsLevel MetricsLevelConfig) error {
	switch metricsLevel {
	case MetricsLevelNone:
		// Do not register any metrics
	case MetricsLevelAggregated:
		prometheus.MustRegister(GlobalParserHits, GlobalParserHitsOk, GlobalParserHitsKo,
			GlobalCsInfo, GlobalParsingHistogram, GlobalPourHistogram,
			BucketsUnderflow, BucketsCanceled, BucketsInstantiation, BucketsOverflow,

View on GitHub (pinned to 909b515798)

Solutions

  1. Set metrics level to 'full' (default) or 'aggregated' in the configuration.
  2. Check for typos and casing; values are lowercase and compared exactly.
  3. Validate user input against metrics.MetricsLevelFull / MetricsLevelAggregated before calling RegisterMetrics.

Example fix

// before
metricsLevel := strings.ToLower(cfg.Prometheus.MetricsLevel) // "verbose"
// after
if metricsLevel != string(metrics.MetricsLevelFull) && metricsLevel != string(metrics.MetricsLevelAggregated) {
    metricsLevel = string(metrics.MetricsLevelDefault)
}
Defensive patterns

Strategy: validation

Validate before calling

switch metricsLevel {
case string(metrics.MetricsLevelFull), string(metrics.MetricsLevelAggregated):
    // ok
default:
    metricsLevel = string(metrics.MetricsLevelDefault)
}

Type guard

func validMetricsLevel(s string) bool {
    return s == string(metrics.MetricsLevelFull) || s == string(metrics.MetricsLevelAggregated)
}

Try / catch

if err := metrics.RegisterMetrics(level); err != nil {
    if errors.Is(err, metrics.ErrInvalidMetricsLevel) {
        log.Warnf("bad metrics level %q, using default", level)
        metrics.RegisterMetrics(string(metrics.MetricsLevelDefault))
    }
}

Prevention

When it happens

Trigger: Calling metrics.RegisterMetrics with a metrics_level config string not in {"full", "aggregated"} — e.g. 'basic', 'none', 'verbose', or a value with different casing ('Full').

Common situations: Typo in prometheus/metrics_level config key, copying config from another product with different level names, or env-var driven configuration feeding an unexpected string.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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