{"record":{"id":"eb8f6ad3eccd5fe8","repo":"stamparm/maltrail","slug":"stats-endpoint-disabled-e","errorCode":null,"errorMessage":"stats endpoint disabled: {e}","messagePattern":"stats endpoint disabled: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sensor/src/main.rs","lineNumber":598,"sourceCode":"                        }\n                    }\n                }\n            })\n            .ok();\n    }\n\n    // --- Prometheus endpoint ---------------------------------------------------\n    // Opt-in, and never fatal: a sensor that cannot bind its metrics port must still detect.\n    if !cfg.stats_address.is_empty() {\n        match maltrail_sensor::stats::spawn(&cfg.stats_address, registry.clone(), Instant::now()) {\n            Ok(bound) => {\n                if !args.quiet {\n                    cprintln!(\"[i] metrics endpoint: http://{bound}/metrics\");\n                }\n            }\n            Err(e) => {\n                ceprintln!(\"[!] metrics endpoint disabled: {e}\");\n                output::log_error(&format!(\"stats endpoint disabled: {e}\"), true);\n            }\n        }\n    }\n\n    // --- metrics thread --------------------------------------------------------\n    if cfg.metrics_interval > 0 && !cfg.is_offline_replay() {\n        let reg_metrics = registry.clone();\n        let shutdown_metrics = shutdown.clone();\n        let interval = Duration::from_secs(cfg.metrics_interval);\n        std::thread::Builder::new()\n            .name(\"metrics\".into())\n            .spawn(move || {\n                let mut next = Instant::now() + interval;\n                loop {\n                    std::thread::sleep(Duration::from_millis(500));\n                    if shutdown_metrics.load(Ordering::Relaxed) {\n                        break;\n                    }","sourceCodeStart":580,"sourceCodeEnd":616,"githubUrl":"https://github.com/stamparm/maltrail/blob/77cfb06d7606506d101bbcec0786c77166c4255e/sensor/src/main.rs#L580-L616","documentation":"The sensor's metrics/stats HTTP endpoint failed to bind its listener; the code logs \"stats endpoint disabled: {e}\" via output::log_error after printing the bind error to stderr. Monitoring is lost for this process, but the sensor itself keeps running.","triggerScenarios":"The metrics server bind (TcpListener::bind or equivalent) returns Err(e) in run(): the configured address/port is already in use, the address is not local, or binding to a privileged port without permissions.","commonSituations":"Two sensor instances started with the same metrics port (address-already-in-use); old process still holding the port during restart; binding to :80/:9100-style low ports as non-root; container network namespace conflicts.","solutions":["Check for a port conflict with `ss -ltnp | grep <port>` and stop the other process or change the metrics port.","Choose an unprivileged port (e.g. >1024) if running as a non-root user.","Bind to 0.0.0.0 or a valid local IP instead of an address not assigned to the host.","Read the ({e}) text to confirm the bind error kind before further changes."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pick a free port before starting the metrics server\nlet listener = std::net::TcpListener::bind((\"0.0.0.0\", 0))?;\nlet free_port = listener.local_addr()?.port();","typeGuard":"fn port_bindable(port: u16) -> bool {\n    std::net::TcpListener::bind((\"0.0.0.0\", port)).is_ok()\n}","tryCatchPattern":"match TcpListener::bind(addr) {\n    Ok(l) => start_metrics(l),\n    Err(e) => { log_metrics_disabled(&e); continue_sensor_without_metrics(); }\n}","preventionTips":["Use a unique, unprivileged metrics port per instance","Check `ss -ltnp` for port conflicts before deployment","In containers, publish/avoid conflicting host port mappings explicitly"],"tags":["rust","metrics","bind","port-conflict"],"backgroundTag":"address-already-in-use","analyzedSha":"77cfb06d7606506d101bbcec0786c77166c4255e","analyzedAt":"2026-09-13T03:50:16.010Z","contentChangedAt":"2026-09-13T03:50:16.010Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}