{"record":{"id":"238930b8af036c9e","repo":"tailscale/tailscale","slug":"could-not-set-tcp-rx-buf-size-v","errorCode":null,"errorMessage":"could not set TCP RX buf size: %v","messagePattern":"could not set TCP RX buf size: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"wgengine/netstack/netstack.go","lineNumber":316,"sourceCode":"\t// features are not (yet) implemented, and socket buffer memory is not\n\t// controlled within gVisor, e.g. we allocate *stack.PacketBuffer's for the\n\t// write path within Tailscale. Therefore, we loosen our understanding of\n\t// the relationship between these Linux and gVisor tunables. The chosen\n\t// values are biased towards higher throughput on high bandwidth-delay\n\t// product paths, except on memory-constrained platforms.\n\ttcpRXBufOpt := tcpip.TCPReceiveBufferSizeRangeOption{\n\t\t// Min is unused by gVisor at the time of writing, but partially plumbed\n\t\t// for application by the TCP_WINDOW_CLAMP socket option.\n\t\tMin: tcpRXBufMinSize,\n\t\t// Default is used by gVisor at socket creation.\n\t\tDefault: tcpRXBufDefSize,\n\t\t// Max is used by gVisor to cap the advertised receive window post-read.\n\t\t// (tcp_moderate_rcvbuf=true, the default).\n\t\tMax: tcpRXBufMaxSize,\n\t}\n\ttcpipErr := ipstack.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpRXBufOpt)\n\tif tcpipErr != nil {\n\t\treturn fmt.Errorf(\"could not set TCP RX buf size: %v\", tcpipErr)\n\t}\n\ttcpTXBufOpt := tcpip.TCPSendBufferSizeRangeOption{\n\t\t// Min in unused by gVisor at the time of writing.\n\t\tMin: tcpTXBufMinSize,\n\t\t// Default is used by gVisor at socket creation.\n\t\tDefault: tcpTXBufDefSize,\n\t\t// Max is used by gVisor to cap the send window.\n\t\tMax: tcpTXBufMaxSize,\n\t}\n\ttcpipErr = ipstack.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpTXBufOpt)\n\tif tcpipErr != nil {\n\t\treturn fmt.Errorf(\"could not set TCP TX buf size: %v\", tcpipErr)\n\t}\n\treturn nil\n}\n\n// Create creates and populates a new Impl.\nfunc Create(logf logger.Logf, tundev *tstun.Wrapper, e wgengine.Engine, mc *magicsock.Conn, dialer *tsdial.Dialer, dns *dns.Manager, pm *proxymap.Mapper) (*Impl, error) {","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/tailscale/tailscale/blob/5201273aec737d6372ab7423c31c04ca3ca2a0c2/wgengine/netstack/netstack.go#L298-L334","documentation":"setTCPBufSizes: gVisor netstack rejected the TCPReceiveBufferSizeRangeOption transport option while tuning RX buffer sizes. An internal netstack configuration failure at subsystem creation; the wrapped tcpip error explains why.","triggerScenarios":"Thrown at wgengine/netstack/netstack.go:315 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Reduce the requested TCP receive buffer size to a value the kernel permits (check /proc/sys/net/ipv4/tcp_rmem).","Ensure tailscaled has CAP_NET_ADMIN or the privileges needed to tune socket buffers."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"5201273aec737d6372ab7423c31c04ca3ca2a0c2","analyzedAt":"2026-08-18T08:17:25.280Z","contentChangedAt":"2026-08-18T08:17:25.280Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}