slackhq/nebula · critical

create TUN device failed: %w

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).

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)

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.