slackhq/nebula · error

CTLIOCGINFO: %v

Error message

CTLIOCGINFO: %v

What it means

After opening the AF_SYSTEM socket, newTun issues the CTLIOCGINFO ioctl to resolve the utun kernel control ID from the control name (com.apple.net.utun_control). If that ioctl fails, this error wraps the errno. Without the control ID the subsequent connect cannot identify the kernel control.

Source

Thrown at overlay/tun_darwin.go:102

		if err != nil || ifIndex < 0 {
			// NOTE: we don't make this error so we don't break existing
			// configs that set a name before it was used.
			l.Warn("interface name must be utun[0-9]+ on Darwin, ignoring")
			ifIndex = -1
		}
	}

	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)

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Run nebula directly on macOS (not inside a container/VM without utun support).
  2. Verify the binary is built for darwin (GOOS=darwin); a mismatched build cannot access macOS kernel controls.
  3. Re-run with elevated permissions to rule out permission-based ioctl failures.
  4. Reboot the host if the network kernel extensions are in a bad state.
Defensive patterns

Strategy: retry

Try / catch

if err := start(); err != nil && strings.Contains(err.Error(), "CTLIOCGINFO") {
    // transient kernel state: bounded retry with backoff, then escalate
    time.Sleep(500 * time.Millisecond)
    return start()
}

Prevention

When it happens

Trigger: unix.IoctlCtlInfo(fd, ctlInfo) returns an error because the utun control name is not registered with the kernel, the fd is invalid, or the process lacks permission to issue ioctls on the system socket.

Common situations: Running in restricted environments (containers on macOS hosts, virtualized CI runners) where the utun kernel control is unavailable; corrupted or non-Darwin kernel; running as a user blocked from kernel controls.

Related errors


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