vectordotdev/vector · error

Invalid cache settings: {e:?}

Error message

Invalid cache settings: {e:?}

What it means

MetricNormalizer is the per-sink metrics cache/normalizer that tracks metric series before buffering. with_config runs NormalizerConfig::validate() and panics at component construction if any cache setting is explicitly zero: max_bytes = Some(0) (InvalidMaxBytes), max_events = Some(0) (InvalidMaxEvents), or time_to_live = Some(0) (InvalidTimeToLive). This is a fail-fast check: a degenerate cache is rejected at startup instead of mis-normalizing metrics at runtime.

Source

Thrown at src/sinks/util/buffer/metrics/normalize.rs:154

/// A self-contained metric normalizer.
///
/// The normalization state is stored internally, and it can only be created from a normalizer implementation that is
/// either `Default` or is constructed ahead of time, so it is primarily useful for constructing a usable normalizer
/// via implicit conversion methods or when no special parameters are required for configuring the underlying normalizer.
pub struct MetricNormalizer<N> {
    state: MetricSet,
    normalizer: N,
}

impl<N> MetricNormalizer<N> {
    /// Creates a new normalizer with the given configuration.
    pub fn with_config<D: NormalizerSettings + Clone>(
        normalizer: N,
        config: NormalizerConfig<D>,
    ) -> Self {
        let settings = config
            .validate()
            .unwrap_or_else(|e| panic!("Invalid cache settings: {e:?}"))
            .into_settings();
        Self {
            state: MetricSet::new(settings),
            normalizer,
        }
    }

    /// Creates a new normalizer with a time-to-live policy.
    pub fn with_ttl(normalizer: N, ttl: Duration) -> Self {
        Self {
            state: MetricSet::with_policies(None, Some(TtlPolicy::new(ttl))),
            normalizer,
        }
    }

    /// Gets a mutable reference to the current metric state for this normalizer.
    pub const fn get_state_mut(&mut self) -> &mut MetricSet {
        &mut self.state

View on GitHub (pinned to 3708c39b12)

Solutions

  1. Read the {e:?} payload in the panic - it names the exact offending field (max_bytes / max_events / time_to_live)
  2. Set the offending field to a positive value or remove it so the sink's NormalizerSettings defaults apply
  3. Run `vector validate <config>` on the config to catch it at check time instead of process start
  4. If a stock Vector config produces zeros here, capture the config and open an issue - defaults must never resolve to 0

Example fix

// before
let normalizer = MetricNormalizer::with_config(inner, config); // panics if any field is Some(0)

// after
let config = config.validate().map_err(|e| format!("invalid cache settings: {e:?}"))?;
let normalizer = MetricNormalizer::with_config(inner, config);
Defensive patterns

Strategy: validation

Validate before calling

let cfg = NormalizerConfig::<D> { max_bytes: Some(268_435_488), max_events: Some(500_000), time_to_live: Some(600), ..Default::default() };
match cfg.validate() {
    Ok(valid) => { let _ = MetricNormalizer::with_config(inner, valid); }
    Err(e) => { /* reject the config with a proper error; do not construct */ }
}

Prevention

When it happens

Trigger: Constructing a metrics sink whose normalizer config contains max_bytes: 0, max_events: 0, or time_to_live: 0 (explicitly set values, not omitted ones); any code path that calls MetricNormalizer::with_config without pre-validating NormalizerConfig.

Common situations: Config generation that writes 0 as a placeholder, custom Vector builds deriving normalizer settings arithmetically from another buffer config, or version changes that remapped which sink option lands in these fields. Stock defaults (None falling back to the sink's NormalizerSettings) never trip this.

Related errors


AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20). Data as JSON: /api/errors/82bec87884e9a296. Report an issue: GitHub.