{"record":{"id":"8b4ba36057a90da1","repo":"slackhq/nebula","slug":"could-not-enable-tcp-sack-v","errorCode":null,"errorMessage":"could not enable TCP SACK: %v","messagePattern":"could not enable TCP SACK: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/service.go","lineNumber":80,"sourceCode":"\t\t}\n\t}()\n\n\tctx := control.Context()\n\teg, ctx := errgroup.WithContext(ctx)\n\ts := Service{\n\t\teg:      eg,\n\t\tcontrol: control,\n\t}\n\ts.mu.listeners = map[uint16]*tcpListener{}\n\n\ts.ipstack = stack.New(stack.Options{\n\t\tNetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},\n\t\tTransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol4, icmp.NewProtocol6},\n\t})\n\tsackEnabledOpt := tcpip.TCPSACKEnabled(true) // TCP SACK is disabled by default\n\ttcpipErr := s.ipstack.SetTransportProtocolOption(tcp.ProtocolNumber, &sackEnabledOpt)\n\tif tcpipErr != nil {\n\t\treturn nil, fmt.Errorf(\"could not enable TCP SACK: %v\", tcpipErr)\n\t}\n\tlinkEP := channel.New( /*size*/ 512 /*mtu*/, 1280, \"\")\n\tif tcpipProblem := s.ipstack.CreateNIC(nicID, linkEP); tcpipProblem != nil {\n\t\treturn nil, fmt.Errorf(\"could not create netstack NIC: %v\", tcpipProblem)\n\t}\n\tipv4Subnet, _ := tcpip.NewSubnet(tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00}), tcpip.MaskFrom(strings.Repeat(\"\\x00\", 4)))\n\ts.ipstack.SetRouteTable([]tcpip.Route{\n\t\t{\n\t\t\tDestination: ipv4Subnet,\n\t\t\tNIC:         nicID,\n\t\t},\n\t})\n\n\tipNet := device.Networks()\n\tpa := tcpip.ProtocolAddress{\n\t\tAddressWithPrefix: tcpip.AddrFromSlice(ipNet[0].Addr().AsSlice()).WithPrefix(),\n\t\tProtocol:          ipv4.ProtocolNumber,\n\t}","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/service/service.go#L62-L98","documentation":"In netstack New (service/service.go), after creating the gVisor ipstack, TCP SACK is enabled via SetTransportProtocolOption; any tcpip error is fatal and reported as this message. SACK is required for the tunneled TCP stack to behave well, so the library fails fast.","triggerScenarios":"service.New is called (via doService, run, or newSimpleService) and the gVisor netstack rejects the TCPSACKEnabled option — practically only when the TCP protocol was not registered on the stack or a gVisor version/API incompatibility exists.","commonSituations":"Custom builds where tcp.NewProtocol was dropped from TransportProtocols; vendored gVisor fork with different option semantics; upstream gVisor API change breaking SetTransportProtocolOption.","solutions":["Ensure tcp.NewProtocol is included in TransportProtocols when creating the stack","Update or pin the gVisor dependency to a version compatible with this code","Rebuild with the unmodified stack configuration from service/service.go","Capture the wrapped tcpipErr (%v) to identify the exact tcpip error code"],"exampleFix":"// before\nTransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol, icmp.NewProtocol4, icmp.NewProtocol6}\n// after\nTransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol4, icmp.NewProtocol6}","handlingStrategy":"try-catch","validationCode":"// ensure protocols registered before New:\nstacks := []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol4, icmp.NewProtocol6}","typeGuard":null,"tryCatchPattern":"svc, err := service.New(...)\nif err != nil {\n    if strings.Contains(err.Error(), \"TCP SACK\") {\n        log.Fatalf(\"netstack TCP setup failed (check gVisor deps/protocol registration): %v\", err)\n    }\n    return err\n}","preventionTips":["Keep tcp.NewProtocol registered when customizing stack creation","Pin gVisor versions; test after dependency upgrades","Log the wrapped tcpip error code for diagnosis"],"tags":["netstack","tcp","gvisor"],"backgroundTag":"netstack-configuration-error","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"}