{"record":{"id":"a4b73045544c15e3","repo":"slackhq/nebula","slug":"failed-to-enable-offload-on-multiqueue-tun-fd-w","errorCode":null,"errorMessage":"failed to enable offload on multiqueue tun fd: %w","messagePattern":"failed to enable offload on multiqueue tun fd: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"overlay/tun_linux.go","lineNumber":353,"sourceCode":"\n\tfd, err := unix.Open(\"/dev/net/tun\", os.O_RDWR, 0)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tflags := uint16(unix.IFF_TUN | unix.IFF_NO_PI | unix.IFF_MULTI_QUEUE)\n\tif t.vnetHdr {\n\t\tflags |= unix.IFF_VNET_HDR\n\t}\n\tif _, err = tunSetIff(fd, t.Device, flags); err != nil {\n\t\t_ = unix.Close(fd)\n\t\treturn err\n\t}\n\n\tif t.vnetHdr {\n\t\tif err = ioctl(uintptr(fd), unix.TUNSETOFFLOAD, uintptr(t.offloadFlags)); err != nil {\n\t\t\t_ = unix.Close(fd)\n\t\t\treturn fmt.Errorf(\"failed to enable offload on multiqueue tun fd: %w\", err)\n\t\t}\n\t}\n\n\terr = t.readers.Add(fd)\n\tif err != nil {\n\t\t_ = unix.Close(fd)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (t *tun) RoutesFor(ip netip.Addr) routing.Gateways {\n\tr, _ := t.routeTree.Load().Lookup(ip)\n\treturn r\n}\n\nfunc (t *tun) deviceBytes() (o [16]byte) {","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/overlay/tun_linux.go#L335-L371","documentation":"This error is returned by tun.addQueue when creating a multiqueue tun device: the TUNSETOFFLOAD ioctl that enables checksum/segmentation offload on a newly opened queue file descriptor failed. The original fd is closed and the wrapped kernel error is included via %w, so the underlying cause (e.g. EINVAL, ENOTSUP) is always embedded. It only fires when vnetHdr is true, i.e. when offload/vnet-header support was negotiated.","triggerScenarios":"Calling Queues() (which calls addQueue) on a Linux tun with vnetHdr enabled when the kernel rejects the TUNSETOFFLOAD flags — e.g. offloadFlags contains features the kernel/driver doesn't support, the fd is not a valid tun attach fd, or the device was already detached.","commonSituations":"Running on older kernels or virtualized NICs (some cloud hypervisors) that don't support all requested offload features like TSO/UFO; containers with restricted device access; mismatched nebula build vs kernel capabilities.","solutions":["Inspect the wrapped error (%w) with errors.Unwrap to identify the errno; EINVAL usually means unsupported offload flags.","Update the kernel or run on a host whose tun driver supports the requested offload features.","Run nebula with offload disabled (e.g. older tun config path or a build/config that leaves vnetHdr off) if the platform can't support it.","Check that the process has permission to attach to the tun device (CAP_NET_ADMIN) and that the fd is valid."],"exampleFix":"// before: opaque failure on kernels without UFO support\noffloadFlags := unix.TUNSETOFFLOAD // all features requested\n// after: retry with progressively fewer features or log the unwrapped cause\nif err := ioctl(uintptr(fd), unix.TUNSETOFFLOAD, uintptr(t.offloadFlags)); err != nil {\n    t.l.Warn(\"offload unsupported, continuing without\", \"err\", err)\n}","handlingStrategy":"fallback","validationCode":"// check kernel offload support before enabling vnet hdr\nflags := unix.TUN_F_CSUM | unix.TUN_F_TSO4 | unix.TUN_F_TSO6\nif err := ioctl(uintptr(fd), unix.TUNSETOFFLOAD, uintptr(flags)); err != nil {\n    log.Warn(\"offload unsupported, falling back to no-offload\", \"err\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := startOverlay(); err != nil {\n    if strings.Contains(err.Error(), \"failed to enable offload on multiqueue tun fd\") {\n        // unwrap and retry without offload\n        log.Warn(\"retrying without offload\", \"cause\", errors.Unwrap(err))\n    } else { return err }\n}","preventionTips":["Pin deployments to kernels known to support the requested TUNSETOFFLOAD features","Test tun startup on your hypervisor/cloud image before rollout","Log errors.Unwrap(err) to capture the errno for support tickets"],"tags":["network","tun","linux","ioctl"],"backgroundTag":"tun-offload-ioctl-failed","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}