{"record":{"id":"6980007b09a403c8","repo":"orf/gping","slug":"failed-to-create-a-winpinger-instance","errorCode":null,"errorMessage":"Failed to create a WinPinger instance","messagePattern":"Failed to create a WinPinger instance","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pinger/src/windows.rs","lineNumber":67,"sourceCode":"                                matches!(addr.ip(), IpAddr::V4(_))\n                            }\n                        })\n                        .collect()\n                };\n                if selected_ips.is_empty() {\n                    return Err(PingCreationError::HostnameError {\n                        hostname: domain.clone(),\n                        err: std::io::Error::other(\"no IPs found\"),\n                    });\n                }\n                selected_ips[0].ip()\n            }\n        };\n\n        let (tx, rx) = mpsc::channel();\n\n        thread::spawn(move || {\n            let pinger = WinPinger::new().expect(\"Failed to create a WinPinger instance\");\n            let mut buffer = Buffer::new();\n            loop {\n                match pinger.send(parsed_ip.clone(), &mut buffer) {\n                    Ok(rtt) => {\n                        if tx\n                            .send(PingResult::Pong(\n                                Duration::from_millis(rtt as u64),\n                                \"\".to_string(),\n                            ))\n                            .is_err()\n                        {\n                            break;\n                        }\n                    }\n                    Err(_) => {\n                        // Fuck it. All errors are timeouts. Why not.\n                        if tx.send(PingResult::Timeout(\"\".to_string())).is_err() {\n                            break;","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/orf/gping/blob/681bd79b18ea21783cb54ac2b95a1768d64792fb/pinger/src/windows.rs#L49-L85","documentation":"This panic comes from an `.expect(\"Failed to create a WinPinger instance\")` on `winping::Pinger::new()` inside the background thread spawned by `WindowsPinger::start()` (pinger/src/windows.rs:67). `WinPinger::new()` wraps the Windows ICMP API (`IcmpCreateFile`); when that handle cannot be created, the Result is an Err and the `expect` panics the thread. Because the panic happens in a spawned thread, `start()` still returns a receiver, but the receiver silently never yields pings and the panic message only surfaces if the thread's panic hook prints it.","triggerScenarios":"Calling `WindowsPinger::start()` (via `pinger::Pinger::from_options(...)` then `.start()`) when `winping::Pinger::new()` fails: running on a non-Windows platform with the Windows code path compiled in (winping is Windows-only and its non-Windows build stubs fail), `IcmpCreateFile` failing due to ICMP support being unavailable/disabled, or resource/handle exhaustion in the process.","commonSituations":"Cross-compiling or running the crate on Linux/macOS while the Windows pinger gets selected (e.g. wrong cfg dispatch); Windows environments where raw ICMP is blocked by security policy, service, or sandbox (some containers, stripped-down Windows images); system handle limits exhausted after many pinger instances; older winping versions where `new()` has different failure behavior.","solutions":["Ensure the Windows pinger is only selected on Windows targets (cfg(target_os = \"windows\") dispatch in the library that picks the Pinger impl); on Linux/macOS use the Unix pinger instead of the winping-based one.","Run on a Windows system where the ICMP (iphlpapi) facilities are available and not blocked by policy/antivirus/firewall security software.","Update the winping dependency to the latest version and check its docs for known `Pinger::new()` failure modes.","Patch or wrap `start()` so `WinPinger::new()` failure is returned as `PingCreationError` instead of panicking via `expect` inside the thread.","Check for ICMP handle leaks: if the app creates many `WindowsPinger` instances, drop old ones so Windows can reclaim IcmpFile handles."],"exampleFix":"// before\nlet pinger = WinPinger::new().expect(\"Failed to create a WinPinger instance\");\n// after\nlet pinger = match WinPinger::new() {\n    Ok(p) => p,\n    Err(e) => {\n        let _ = tx.send(PingResult::Timeout(format!(\"WinPinger init failed: {e}\")));\n        return; // or propagate via a Result channel instead of panicking\n    }\n};","handlingStrategy":"try-catch","validationCode":"if cfg!(not(target_os = \"windows\")) {\n    return Err(PingCreationError::UnsupportedPlatform); // pick a Unix pinger instead\n}\n// On Windows, verify winping initializes before relying on start():\nlet probe = winping::Pinger::new().map_err(|_| PingCreationError::Other)?;","typeGuard":"fn winpinger_available() -> bool {\n    cfg!(target_os = \"windows\") && winping::Pinger::new().is_ok()\n}","tryCatchPattern":"// panic occurs in a spawned thread; catch at thread boundary\nlet rx = pinger.start()?;\nlet handle = thread::Builder::new()\n    .spawn_scoped(scope, move || {\n        let result = std::panic::catch_unwind(|| {\n            // code that calls start() and reads from rx\n        });\n        if result.is_err() {\n            eprintln!(\"pinger thread panicked: WinPinger::new failed\");\n        }\n    })?;\n// Or, in the consuming loop, detect a receiver that never yields:\nmatch rx.recv_timeout(Duration::from_secs(5)) {\n    Err(mpsc::RecvTimeoutError::Timeout) => eprintln!(\"pinger thread likely panicked at init\"),\n    other => other,\n}","preventionTips":["Only construct WindowsPinger on Windows targets; gate selection with cfg(target_os = \"windows\").","Patch the library to return a Result from start() instead of using expect() in the spawned thread.","Smoke-test WinPinger::new() at application startup on Windows before starting background ping loops.","Avoid environments that strip ICMP support (hardened sandboxes, stripped containers) for this code path.","Watch for handle exhaustion: reuse one pinger instance rather than creating many."],"tags":["windows","icmp","panic","winping","thread-panic"],"backgroundTag":"unsupported-platform","analyzedSha":"681bd79b18ea21783cb54ac2b95a1768d64792fb","analyzedAt":"2026-09-08T03:01:05.800Z","contentChangedAt":"2026-09-08T03:01:05.800Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}