slackhq/nebula · critical

failed to set tun mtu: %w

Error message

failed to set tun mtu: %w

What it means

This error is returned by the NetBSD tun Activate method when the SIOCSIFMTU ioctl fails, i.e. the interface MTU could not be set to the configured value. Without setting the MTU, the tunnel may fragment or drop packets, so activation aborts. The error wraps the underlying errno for diagnosis.

Source

Thrown at overlay/tun_netbsd.go:318

	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
		}
	}

	return t.addRoutes(false)
}

func (t *tun) doIoctlByName(ctl uintptr, value uint32) error {
	s, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, unix.IPPROTO_IP)
	if err != nil {
		return err
	}
	defer syscall.Close(s)

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Check the tun.mtu config value is a sane positive number (typically 1300–1500) and remove/fix extreme values.
  2. Ensure the process runs as root so SIOCSIFMTU is permitted.
  3. Inspect the wrapped errno via errors.Is/As to distinguish EPERM from EINVAL.
  4. Confirm the tun device was successfully opened and configured before Activate is called.

Example fix

// before
 tun:
   mtu: 0
// after
 tun:
   mtu: 1300
Defensive patterns

Strategy: validation

Validate before calling

mtu := c.GetInt("tun.mtu", 1300)
if mtu <= 0 || mtu > 9000 {
    return fmt.Errorf("invalid tun.mtu %d; use a value between 1 and 9000 (typical: 1300-1500)", mtu)
}
if os.Geteuid() != 0 {
    return fmt.Errorf("setting interface MTU requires root privileges")
}

Try / catch

if err := t.Activate(); err != nil {
    var syscallErr syscall.Errno
    if errors.As(err, &syscallErr) && syscallErr == unix.EINVAL {
        // MTU value rejected — fall back to a sane default
    }
    return err
}

Prevention

When it happens

Trigger: Calling Activate() where doIoctlByName(unix.SIOCSIFMTU, mtu) fails — typically an invalid MTU value (0, negative, or below the interface minimum), or the fd is not associated with a live interface.

Common situations: A config file with tun.mtu set to an out-of-range value; running without root; the tun interface being destroyed before activation completes.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/8d8a2a731c90f6e7. Report an issue: GitHub.