slackhq/nebula · critical

create TUN device failed

Error message

create TUN device failed: %w

What it means

newTun failed twice to create the wintun TUN device via wintun.CreateTUNWithRequestedGUID, even after one retry. The error is wrapped in a NameError carrying the requested deviceName. This library throws it because the underlying wintun driver refused to create the interface (driver missing, name conflict, or permission problem).

Solutions

  1. Run the process as Administrator
  2. Ensure a compatible wintun.dll is present next to the binary or in PATH
  3. Delete stale wintun adapters (Device Manager > network adapters, or 'netcfg -d' as last resort)
  4. Update wintun.dll/driver to the latest release
  5. Check the tun.device name config for invalid characters or a conflicting existing adapter

Example fix

// before
sudo nebula -config config.yml
// after (elevated PowerShell)
Start-Process nebula -ArgumentList '-config config.yml' -Verb RunAs
Defensive patterns

Strategy: try-catch

Validate before calling

// Windows, before starting: require elevation and wintun.dll presence
if !windows.GetCurrentProcessToken().IsElevated() {
    return errors.New("nebula requires administrator privileges on Windows")
}
if _, err := os.Stat(filepath.Join(exeDir, "wintun.dll")); err != nil {
    return errors.New("wintun.dll not found next to the binary")
}

Type guard

var nameErr *overlay.NameError
if errors.As(err, &nameErr) {
    log.Printf("TUN creation failed for device %q: %v", nameErr.Name, nameErr.Underlying)
}

Try / catch

tun, err := overlay.NewTunFromConf(...)
if err != nil {
    var ne *overlay.NameError
    if errors.As(err, &ne) {
        log.Fatalf("create TUN %s failed: %v", ne.Name, ne.Underlying)
    }
    return err
}

Prevention

When it happens

Trigger: Calling newTun on Windows when the wintun.dll driver is missing/not loadable, the requested interface name is invalid or already in use, the process lacks administrator privileges, or the MTU is invalid — in both initial attempt and the single retry.

Common situations: Running nebula without elevated privileges; missing wintun.dll in PATH or alongside the binary; stale/orphaned wintun adapter from a previous crash; outdated wintun driver conflicting with WireGuard installs.

Related errors


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

Appendix: source

Thrown at overlay/tun_windows.go:101

		l:               l,
	}

	err = t.reload(c, true)
	if err != nil {
		return nil, err
	}

	var tunDevice wintun.Device
	tunDevice, err = wintun.CreateTUNWithRequestedGUID(deviceName, guid, t.MTU)
	if err != nil {
		// Windows 10 has an issue with unclean shutdowns not fully cleaning up the wintun device.
		// Trying a second time resolves the issue.
		l.Debug("Failed to create wintun device, retrying", "error", err)
		tunDevice, err = wintun.CreateTUNWithRequestedGUID(deviceName, guid, t.MTU)
		if err != nil {
			return nil, &NameError{
				Name:       deviceName,
				Underlying: fmt.Errorf("create TUN device failed: %w", err),
			}
		}
	}
	t.tun = tunDevice.(*wintun.NativeTun)

	c.RegisterReloadCallback(func(c *config.C) {
		err := t.reload(c, false)
		if err != nil {
			util.LogWithContextIfNeeded("failed to reload tun device", err, t.l)
		}
	})

	return t, nil
}

func (t *winTun) reload(c *config.C, initial bool) error {
	change, routes, err := getAllRoutesFromConfig(c, t.vpnNetworks, initial)
	if err != nil {

View on GitHub (pinned to dd8f660c0a)