slackhq/nebula · error
failed to set tun device mode: %w
Error message
failed to set tun device mode: %w
What it means
Activate() puts the tun device into IFF_BROADCAST mode via the TUNSIFMODE ioctl. If that ioctl fails, this error wraps the errno, meaning the kernel refused to set the device mode (device in wrong state, bad descriptor, or permission issue).
Source
Thrown at overlay/tun_netbsd.go:307
if err != nil {
return err
}
defer syscall.Close(s)
if err := ioctl(uintptr(s), SIOCAIFADDR_IN6, uintptr(unsafe.Pointer(&req))); err != nil {
return fmt.Errorf("failed to set tun address %s: %s", cidr.Addr().String(), err)
}
return nil
}
return fmt.Errorf("unknown address type %v", cidr)
}
func (t *tun) Activate() error {
mode := int32(unix.IFF_BROADCAST)
err := ioctl(uintptr(t.fd), TUNSIFMODE, uintptr(unsafe.Pointer(&mode)))
if err != nil {
return fmt.Errorf("failed to set tun device mode: %w", err)
}
v := 1
err = ioctl(uintptr(t.fd), TUNSIFHEAD, uintptr(unsafe.Pointer(&v)))
if err != nil {
return fmt.Errorf("failed to set tun device head: %w", err)
}
err = t.doIoctlByName(unix.SIOCSIFMTU, uint32(t.MTU))
if err != nil {
return fmt.Errorf("failed to set tun mtu: %w", err)
}
for i := range t.vpnNetworks {
err = t.addIp(t.vpnNetworks[i])
if err != nil {
return err
}View on GitHub (pinned to dd8f660c0a)
Solutions
- Ensure Activate() is called once, right after newTun() and before Close()
- Verify the tun device still exists and the fd is valid (recreate with ifconfig tunN create if destroyed)
- Run with root privileges as TUNSIFMODE requires device access
Example fix
// before tun.Close() tun.Activate() // fd already closed // after tun.Activate() // ... use tun ... tun.Close()
Defensive patterns
Strategy: try-catch
Validate before calling
// call Activate exactly once, immediately after newTun
var activateOnce sync.Once
func safeActivate(t *tun) error {
var err error
activateOnce.Do(func() { err = t.Activate() })
return err
} Try / catch
if err := tun.Activate(); err != nil {
log.Printf("tun activate failed: %v — device may need recreation (ifconfig tunN create)", err)
} Prevention
- Activate immediately after opening, before any I/O
- Do not call Activate concurrently or after Close
- Ensure the device exists and the process is privileged
When it happens
Trigger: ioctl(fd, TUNSIFMODE, IFF_BROADCAST) fails because t.fd is invalid/closed, the device was already configured to an incompatible mode, or the caller lacks privileges.
Common situations: Calling Activate after the device was destroyed; double activation racing with Close; unprivileged execution.
Related errors
- failed to set tun address %s: %s
- failed to set tun device head: %w
- failed to set tun mtu: %w
- failed to set tun mtu: %w
- failed to set tun address %s: %s
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/36d199876b64512a.
Report an issue: GitHub.