slackhq/nebula · error

failed to set tun mtu: %w

Error message

failed to set tun mtu: %w

What it means

Activate() first sets the interface MTU via the SIOCSIFMTU ioctl (through doIoctlByName). Failure is wrapped with 'failed to set tun mtu'. The MTU value comes from the tun.mtu config, and the ioctl can fail on permissions or if the value is out of the kernel's accepted range.

Source

Thrown at overlay/tun_openbsd.go:297

		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 {
	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. Set tun.mtu to a sane value (e.g. 1300 for typical VPN overlays)
  2. Run with sufficient privileges
  3. Remove the tun.mtu override to use the default
  4. Check the wrapped errno for the exact kernel reason

Example fix

# before
tun:
  mtu: 90000
# after
tun:
  mtu: 1300
Defensive patterns

Strategy: validation

Validate before calling

mtu := cfg.GetInt("tun.mtu", 1300)
if mtu < 576 || mtu > 65535 {
    return fmt.Errorf("tun.mtu %d out of range", mtu)
}

Try / catch

if err := t.Activate(); err != nil && strings.Contains(err.Error(), "failed to set tun mtu") {
    log.Error("MTU rejected by kernel; check tun.mtu and privileges", "err", err)
    return err
}

Prevention

When it happens

Trigger: t.Activate() invoked during interface bring-up with tun.mtu set to a value the kernel rejects, or the process lacking privileges for SIOCSIFMTU.

Common situations: Setting an extreme MTU (e.g. 0 or >65535) in config; running unprivileged; interface in an unexpected state.

Related errors


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