vectordotdev/vector · critical

Metrics must be initialized

Error message

Metrics must be initialized

What it means

`start_validated` fetches the global metrics `Controller::get()` and panics if none is installed (src/topology/running.rs:1403). Vector's metrics subsystem must be initialized (`init`/`initialize`) before a topology starts, because expiry settings are applied to the global controller.

Solutions

  1. Call the metrics initialization (e.g. `vector::metrics::init(...)` / `Controller::initialize`) before starting the topology.
  2. In embedded usage, replicate the bootstrap performed by vector's main before `start_validated`.
  3. Check startup ordering so no code path can reach topology start before metrics init.

Example fix

// before
let topology = RunningTopology::start_validated(config, abort_tx).await;

// after
vector::metrics::init(&MetricsBuilder::default().build())?; // initialize global controller first
let topology = RunningTopology::start_validated(config, abort_tx).await;
Defensive patterns

Strategy: validation

Validate before calling

if vector::metrics::Controller::get().is_none() {
    return Err("metrics subsystem not initialized; call vector::metrics::init before starting topology".into());
}

Type guard

fn metrics_ready() -> bool { vector::metrics::Controller::get().is_some() }

Prevention

When it happens

Trigger: Starting a validated topology without first calling vector's metrics initialization (e.g. embedding vector as a library and skipping `vector::metrics::init`), or a second init path that dropped the controller.

Common situations: Library embedding of vector, custom binaries using `start_validated` directly, or tests that build a topology without the metrics bootstrap step.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/7f2865a80bc866e3. Report an issue: GitHub.

Appendix: source

Thrown at src/topology/running.rs:1403

            (Some(_), Some(_)) => {
                error!(
                    message = "Cannot set both `expire_metrics` and `expire_metrics_secs`.",
                    internal_log_rate_limit = false
                );
                return None;
            }
            (None, Some(e)) => {
                if e < 0f64 {
                    None
                } else {
                    Some(e)
                }
            }
            (None, None) => Some(300f64),
        };

        if let Err(error) = crate::metrics::Controller::get()
            .expect("Metrics must be initialized")
            .set_expiry(
                expire_metrics,
                config
                    .global
                    .expire_metrics_per_metric_set
                    .clone()
                    .unwrap_or_default(),
            )
        {
            error!(message = "Invalid metrics expiry.", %error, internal_log_rate_limit = false);
            return None;
        }

        let (utilization_emitter, utilization_registry) = pieces
            .utilization
            .take()
            .expect("Topology is missing the utilization metric emitter!");
        let metrics_storage = pieces.metrics_storage.clone();

View on GitHub (pinned to bdb87aeaa4)