slackhq/nebula · error
SYS_CONNECT: %v
Error message
SYS_CONNECT: %v
What it means
newTun connects the control socket to the utun kernel control using SockaddrCtl with the resolved control ID and a unit number derived from the requested interface index (Unit = ifIndex + 1). If unix.Connect fails, this error wraps the errno. Commonly this means the requested utun unit number is already taken or invalid.
Source
Thrown at overlay/tun_darwin.go:110
fd, err := unix.Socket(unix.AF_SYSTEM, unix.SOCK_DGRAM, unix.AF_SYS_CONTROL)
if err != nil {
return nil, fmt.Errorf("system socket: %v", err)
}
var ctlInfo = &unix.CtlInfo{}
copy(ctlInfo.Name[:], utunControlName)
err = unix.IoctlCtlInfo(fd, ctlInfo)
if err != nil {
return nil, fmt.Errorf("CTLIOCGINFO: %v", err)
}
err = unix.Connect(fd, &unix.SockaddrCtl{
ID: ctlInfo.Id,
Unit: uint32(ifIndex) + 1,
})
if err != nil {
return nil, fmt.Errorf("SYS_CONNECT: %v", err)
}
name, err = unix.GetsockoptString(fd, unix.AF_SYS_CONTROL, _UTUN_OPT_IFNAME)
if err != nil {
return nil, fmt.Errorf("failed to retrieve tun name: %w", err)
}
err = unix.SetNonblock(fd, true)
if err != nil {
return nil, fmt.Errorf("SetNonblock: %v", err)
}
t := &tun{
f: os.NewFile(uintptr(fd), ""),
Device: name,
vpnNetworks: vpnNetworks,
DefaultMTU: c.GetInt("tun.mtu", DefaultMTU),
l: l,View on GitHub (pinned to dd8f660c0a)
Solutions
- Remove tun.dev from config (or leave it unset) so macOS assigns the next available utun unit automatically.
- Check `ifconfig` for the utunN device and pick an unused unit if a fixed name is required.
- Kill any stale nebula/VPN processes holding the utun unit and retry.
- Use a lower unit number (macOS reserves utun0-utun3 for system services).
Example fix
// before (nebula.yml) tun: dev: utun3 // after tun: dev: utun50 # or omit 'dev' entirely to auto-assign
Defensive patterns
Strategy: validation
Validate before calling
// before starting nebula, if tun.dev is pinned, verify it is free:
out, _ := exec.Command("ifconfig", devName).Output()
if len(out) > 0 {
return fmt.Errorf("interface %s already exists; unset tun.dev to auto-assign", devName)
} Try / catch
if err := start(); err != nil && strings.Contains(err.Error(), "SYS_CONNECT") {
// utun unit likely in use: clear tun.dev and retry with auto-assigned unit
} Prevention
- Leave tun.dev unset on macOS so the kernel assigns a free utun unit
- Avoid utun0-utun3 which macOS system services reserve
- Clean up stale utun devices after crashes before restarting
When it happens
Trigger: Explicitly configuring a tun device name (e.g. utun5) whose unit number is already in use, requesting a unit above the kernel maximum, or the control ID being stale after kernel state changes.
Common situations: Config tun.dev set to a specific utunN that macOS already allocated (e.g. utun3 used by VPN/icloud private relay); leftover utun from a crashed previous nebula instance.
Related errors
- system socket: %v
- CTLIOCGINFO: %v
- failed to retrieve tun name: %w
- SetNonblock: %v
- unable to discover link_addr for tun interface
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/ca9f21bb66e42301.
Report an issue: GitHub.