{"record":{"id":"147a75cc226d3e37","repo":"slackhq/nebula","slug":"unable-to-open-socket-w","errorCode":null,"errorMessage":"unable to open socket: %w","messagePattern":"unable to open socket: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"udp/udp_linux.go","lineNumber":48,"sourceCode":"\t// udp_linux_writebatch.go.\n\tbw *batchWriter\n\n\tgroSupported bool\n}\n\nfunc NewListener(l *slog.Logger, s Settings) (Conn, error) {\n\taf := unix.AF_INET6\n\tif s.Listen.Addr().Is4() {\n\t\taf = unix.AF_INET\n\t}\n\tsyscall.ForkLock.RLock()\n\tfd, err := unix.Socket(af, unix.SOCK_DGRAM, unix.IPPROTO_UDP)\n\tif err == nil {\n\t\tunix.CloseOnExec(fd)\n\t}\n\tsyscall.ForkLock.RUnlock()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to open socket: %w\", err)\n\t}\n\n\tif s.Multi {\n\t\tif err = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {\n\t\t\t_ = unix.Close(fd)\n\t\t\treturn nil, fmt.Errorf(\"unable to set SO_REUSEPORT: %w\", err)\n\t\t}\n\t}\n\n\tvar sa unix.Sockaddr\n\tport := int(s.Listen.Port())\n\tif s.Listen.Addr().Is4() {\n\t\tsa4 := &unix.SockaddrInet4{Port: port}\n\t\tsa4.Addr = s.Listen.Addr().As4()\n\t\tsa = sa4\n\t} else {\n\t\tsa6 := &unix.SockaddrInet6{Port: port}\n\t\tsa6.Addr = s.Listen.Addr().As16()","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/udp/udp_linux.go#L30-L66","documentation":"NewListener wraps the raw errno from unix.Socket(AF_INET/AF_INET6, SOCK_DGRAM, IPPROTO_UDP) when the kernel refuses to create a UDP socket. The library throws it because without a raw fd it cannot build its StdConn UDP listener at all. The wrapped err is the syscall errno (e.g. EMFILE, ENFILE, EAFNOSUPPORT, EPROTONOSUPPORT).","triggerScenarios":"Calling udp.NewListener (directly or via nebula's interface setup) when the process is out of file descriptors (EMFILE/ENFILE), the address family is unavailable, or UDP sockets are blocked by the kernel/container seccomp profile.","commonSituations":"Containers with a low ulimit -n; Kubernetes pods hitting the node-wide file-descriptor cap; hardened seccomp/AppArmor policies blocking socket(2); kernels built without UDP/IPv6 support.","solutions":["Raise the process/file-descriptor limit (ulimit -n, systemd LimitNOFILE, container rlimit) and restart","Check the wrapped errno in the error chain (errors.Unwrap / %w) to identify the exact syscall failure","Verify the container/runtime seccomp profile permits socket(AF_INET*, SOCK_DGRAM)","Confirm the kernel supports the requested address family (IPv4 vs IPv6) and UDP protocol"],"exampleFix":"// before (shell)\nulimit -n  # 256, too low\n// after (systemd unit)\n[Service]\nLimitNOFILE=65535","handlingStrategy":"try-catch","validationCode":"// pre-flight: ensure fd headroom before starting nebula\nn, err := syscall.Getrlimit(syscall.RLIMIT_NOFILE)\nif err == nil && n.Cur < 1024 {\n    return fmt.Errorf(\"RLIMIT_NOFILE too low (%d); raise it before starting\", n.Cur)\n}","typeGuard":null,"tryCatchPattern":"l, err := udp.NewListener(...)\nif err != nil {\n    var errno syscall.Errno\n    if errors.As(err, &errno) && (errors.Is(errno, syscall.EMFILE) || errors.Is(errno, syscall.ENFILE)) {\n        // raise RLIMIT_NOFILE / retry after freeing fds\n    }\n    return fmt.Errorf(\"udp listener: %w\", err)\n}","preventionTips":["Set LimitNOFILE/ulimit -n generously (e.g. 65535) for nebula units and containers","Check wrapped errno with errors.As(err, &syscall.Errno) to pinpoint the syscall failure","Avoid fd leaks elsewhere in the process; monitor /proc/<pid>/fd count","Test startup in a container with the production seccomp profile"],"tags":["udp","linux","syscall","socket-creation","file-descriptors"],"backgroundTag":"socket-creation-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"}