{"record":{"id":"64eac1b4e997c747","repo":"embassy-rs/embassy","slug":"transmit-error","errorCode":null,"errorMessage":"transmit error: {:?}","messagePattern":"transmit error: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-net-tuntap/src/lib.rs","lineNumber":197,"sourceCode":"            Ok(n) => {\n                buf.set_len(n);\n                Some(buf)\n            }\n            Err(e) if e.kind() == io::ErrorKind::WouldBlock => None,\n            Err(e) => panic!(\"read error: {:?}\", e),\n        }\n    }\n\n    fn can_transmit(&mut self) -> bool {\n        true\n    }\n\n    fn transmit(&mut self, buf: PacketBuf) -> Result<(), PacketBuf> {\n        // todo handle WouldBlock with async\n        match unsafe { self.device.get_mut() }.write(&buf) {\n            Ok(_) => {}\n            Err(e) if e.kind() == io::ErrorKind::WouldBlock => info!(\"transmit WouldBlock\"),\n            Err(e) => panic!(\"transmit error: {:?}\", e),\n        }\n        Ok(())\n    }\n}\n","sourceCodeStart":179,"sourceCodeEnd":202,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-net-tuntap/src/lib.rs#L179-L202","documentation":"The tuntap device panicked because writing a packet to the host's TUN device failed with an error other than WouldBlock (WouldBlock is only logged as 'transmit WouldBlock'). Because the smoltcp Device trait's transmit() cannot report errors, any real write failure (fd closed, interface removed, invalid MTU/argument) escalates to a panic in the driver task.","triggerScenarios":"write() on the TUN fd returns a non-WouldBlock error during transmit(): fd closed or invalid after shutdown, the tun interface deleted at runtime, packet larger than the tun MTU yielding EINVAL, or the device underlying state changed (ENODEV/ENETDOWN).","commonSituations":"Configuring an interface MTU larger than the tun device's actual MTU so oversized writes fail; scripts/NetworkManager tearing down the tun interface while traffic flows; fd closed by another thread during shutdown; container/permission issues surfacing at first write.","solutions":["Align the smoltcp Stack config MTU with the actual tun interface MTU so no oversized packet is written","Keep the tun interface alive for the process lifetime; prevent NetworkManager/scripts from deleting it, and verify with 'ip link show'","Verify /dev/net/tun access and privileges (cap-add NET_ADMIN in containers) before starting the stack","Ensure the tun fd stays open until the network task is fully shut down","Patch the driver locally to log and drop the packet instead of panicking on non-WouldBlock write errors"],"exampleFix":"// before\nErr(e) => panic!(\"transmit error: {:?}\", e),\n// after (local patch)\nErr(e) => {\n    warn!(\"tun write error: {:?}, dropping packet\", e);\n    return Ok(());\n}","handlingStrategy":"validation","validationCode":"// preflight: match configured MTU to the tun device MTU before starting the stack\n// actual=$(ip link show tun0 | grep -o 'mtu [0-9]*' | cut -d' ' -f2)\n// assert configured_mtu <= actual, else writes will fail with EINVAL","typeGuard":"// Rust: classify write errors before escalation\nfn is_fatal_write_error(e: &std::io::Error) -> bool {\n    !matches!(e.kind(), std::io::ErrorKind::WouldBlock | std::io::ErrorKind::Interrupted)\n}","tryCatchPattern":"// run the network task under catch_unwind and restart on failure\nlet result = std::panic::catch_unwind(AssertUnwindSafe(|| network_task()));\nif result.is_err() {\n    error!(\"transmit panic; re-creating tun device and restarting task\");\n}","preventionTips":["Set the smoltcp stack MTU no larger than the tun interface MTU","Keep the tun interface alive and owned by the running user for the app lifetime","Verify privileges (/dev/net/tun, NET_ADMIN) before starting traffic","Close the tun fd only after the network task has fully stopped","Test interface teardown scenarios (link del, restarts) in CI to catch panics early"],"tags":["linux","tun-tap","network","io-error","panic"],"backgroundTag":"file-write-failed","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}