Note: This issue was filed and subsequently corrected by an AI agent (Claude) after an extended debugging session on a real system. All traces, version strings, and symptom descriptions are from actual observed behavior.
Update: The original diagnosis (GIC IPI delivery failure) was incorrect. The issue has been updated with the actual root cause, identified through instrumented debugging with a patched libkrun.
Root cause
In src/devices/src/virtio/net/unixgram.rs, the local bind address is constructed by appending -krun.sock to the peer (gvproxy) socket path:
let local_addr = UnixAddr::new(&PathBuf::from(format!("{}-krun.sock", path.display())))
macOS enforces a 104-byte limit on unix socket paths. The gvproxy socket path is typically ~99 bytes (system temp dir + machine name), so appending -krun.sock (9 bytes) produces a 108-byte path. UnixAddr::new returns ENAMETOOLONG, which propagates as:
Error activating virtio-net (eth0) backend: InvalidAddress(ENAMETOOLONG)
thread 'fc_vcpu 0' panicked at src/devices/src/virtio/mmio.rs:320:14:
Failed to activate device: BadActivate
The vCPU thread panics and exits, but krunkit stays alive. The VM sits frozen at 0% CPU indefinitely. From outside this is indistinguishable from a WFI/interrupt delivery failure — which led to the original misdiagnosis of a GIC bug.
This is not specific to any particular machine name. The peer path length depends on the system temp directory and machine name, both outside libkrun's control. Any configuration where the gvproxy socket path is ≥ 96 bytes will hit this.
System info
- MacBook Pro, Apple M4 Pro, 14 cores, 48 GB RAM
- macOS 26.5 arm64 (Darwin 25.5.0, Build 25F71)
- krunkit 1.2.1 (
slp/krun tap), libkrun 1.18.1
- podman 5.8.2
Steps to reproduce
CONTAINERS_MACHINE_PROVIDER=libkrun podman machine init --cpus 1 my-machine
CONTAINERS_MACHINE_PROVIDER=libkrun podman machine start my-machine
# VM starts, krunkit shows 0% CPU after ~3.5s, never sends ready signal
Multi-CPU configs exhibit the same freeze immediately; the SMP lockup traces in the original filing were from the same underlying panic, not GIC failures.
Proposed fix
Use a short path in /tmp derived from the process ID and a per-call counter, independent of the peer path entirely:
use std::sync::atomic::{AtomicU32, Ordering};
static NET_SOCK_COUNTER: AtomicU32 = AtomicU32::new(0);
let local_path = PathBuf::from(format!(
"/tmp/krun-net-{}-{}.sock",
std::process::id(),
NET_SOCK_COUNTER.fetch_add(1, Ordering::Relaxed)
));
let local_addr = UnixAddr::new(&local_path).map_err(ConnectError::InvalidAddress)?;
The PID ensures uniqueness across concurrent krunkit processes; the counter handles multiple virtio-net devices within the same process. The resulting path is always well under 40 bytes regardless of machine name or system configuration.
Verification
With this fix applied, a 10-vCPU / 35 GiB libkrun machine starts successfully and SSH is reachable on macOS 26.5 (Darwin 25.5.0, Apple M4 Pro).
Root cause
In
src/devices/src/virtio/net/unixgram.rs, the local bind address is constructed by appending-krun.sockto the peer (gvproxy) socket path:macOS enforces a 104-byte limit on unix socket paths. The gvproxy socket path is typically ~99 bytes (system temp dir + machine name), so appending
-krun.sock(9 bytes) produces a 108-byte path.UnixAddr::newreturnsENAMETOOLONG, which propagates as:The vCPU thread panics and exits, but krunkit stays alive. The VM sits frozen at 0% CPU indefinitely. From outside this is indistinguishable from a WFI/interrupt delivery failure — which led to the original misdiagnosis of a GIC bug.
This is not specific to any particular machine name. The peer path length depends on the system temp directory and machine name, both outside libkrun's control. Any configuration where the gvproxy socket path is ≥ 96 bytes will hit this.
System info
slp/kruntap), libkrun 1.18.1Steps to reproduce
CONTAINERS_MACHINE_PROVIDER=libkrun podman machine init --cpus 1 my-machine CONTAINERS_MACHINE_PROVIDER=libkrun podman machine start my-machine # VM starts, krunkit shows 0% CPU after ~3.5s, never sends ready signalMulti-CPU configs exhibit the same freeze immediately; the SMP lockup traces in the original filing were from the same underlying panic, not GIC failures.
Proposed fix
Use a short path in
/tmpderived from the process ID and a per-call counter, independent of the peer path entirely:The PID ensures uniqueness across concurrent krunkit processes; the counter handles multiple virtio-net devices within the same process. The resulting path is always well under 40 bytes regardless of machine name or system configuration.
Verification
With this fix applied, a 10-vCPU / 35 GiB libkrun machine starts successfully and SSH is reachable on macOS 26.5 (Darwin 25.5.0, Apple M4 Pro).