{"record":{"id":"7f2865a80bc866e3","repo":"vectordotdev/vector","slug":"metrics-must-be-initialized","errorCode":null,"errorMessage":"Metrics must be initialized","messagePattern":"Metrics must be initialized","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/topology/running.rs","lineNumber":1403,"sourceCode":"            (Some(_), Some(_)) => {\n                error!(\n                    message = \"Cannot set both `expire_metrics` and `expire_metrics_secs`.\",\n                    internal_log_rate_limit = false\n                );\n                return None;\n            }\n            (None, Some(e)) => {\n                if e < 0f64 {\n                    None\n                } else {\n                    Some(e)\n                }\n            }\n            (None, None) => Some(300f64),\n        };\n\n        if let Err(error) = crate::metrics::Controller::get()\n            .expect(\"Metrics must be initialized\")\n            .set_expiry(\n                expire_metrics,\n                config\n                    .global\n                    .expire_metrics_per_metric_set\n                    .clone()\n                    .unwrap_or_default(),\n            )\n        {\n            error!(message = \"Invalid metrics expiry.\", %error, internal_log_rate_limit = false);\n            return None;\n        }\n\n        let (utilization_emitter, utilization_registry) = pieces\n            .utilization\n            .take()\n            .expect(\"Topology is missing the utilization metric emitter!\");\n        let metrics_storage = pieces.metrics_storage.clone();","sourceCodeStart":1385,"sourceCodeEnd":1421,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/topology/running.rs#L1385-L1421","documentation":"`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.","triggerScenarios":"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.","commonSituations":"Library embedding of vector, custom binaries using `start_validated` directly, or tests that build a topology without the metrics bootstrap step.","solutions":["Call the metrics initialization (e.g. `vector::metrics::init(...)` / `Controller::initialize`) before starting the topology.","In embedded usage, replicate the bootstrap performed by vector's main before `start_validated`.","Check startup ordering so no code path can reach topology start before metrics init."],"exampleFix":"// before\nlet topology = RunningTopology::start_validated(config, abort_tx).await;\n\n// after\nvector::metrics::init(&MetricsBuilder::default().build())?; // initialize global controller first\nlet topology = RunningTopology::start_validated(config, abort_tx).await;","handlingStrategy":"validation","validationCode":"if vector::metrics::Controller::get().is_none() {\n    return Err(\"metrics subsystem not initialized; call vector::metrics::init before starting topology\".into());\n}","typeGuard":"fn metrics_ready() -> bool { vector::metrics::Controller::get().is_some() }","tryCatchPattern":null,"preventionTips":["Always initialize metrics as the first step of any embedding of vector.","Mirror the bootstrap order from vector's main: metrics init -> topology start.","Add an early assert in startup code that the global controller exists."],"tags":["rust","metrics","initialization","panic"],"backgroundTag":"module-init-failed","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}