{"record":{"id":"028b547c784a6d8e","repo":"XTLS/Xray-core","slug":"keepaliveperiod-must-be-between-2-and-60","errorCode":null,"errorMessage":"KeepAlivePeriod must be between 2 and 60","messagePattern":"KeepAlivePeriod must be between 2 and 60","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_internet.go","lineNumber":276,"sourceCode":"\t\t\t}\n\n\t\t\tif c.FinalMask.QuicParams.InitStreamReceiveWindow > 0 && c.FinalMask.QuicParams.InitStreamReceiveWindow < 16384 {\n\t\t\t\treturn nil, errors.New(\"InitStreamReceiveWindow must be at least 16384\")\n\t\t\t}\n\t\t\tif c.FinalMask.QuicParams.MaxStreamReceiveWindow > 0 && c.FinalMask.QuicParams.MaxStreamReceiveWindow < 16384 {\n\t\t\t\treturn nil, errors.New(\"MaxStreamReceiveWindow must be at least 16384\")\n\t\t\t}\n\t\t\tif c.FinalMask.QuicParams.InitConnectionReceiveWindow > 0 && c.FinalMask.QuicParams.InitConnectionReceiveWindow < 16384 {\n\t\t\t\treturn nil, errors.New(\"InitConnectionReceiveWindow must be at least 16384\")\n\t\t\t}\n\t\t\tif c.FinalMask.QuicParams.MaxConnectionReceiveWindow > 0 && c.FinalMask.QuicParams.MaxConnectionReceiveWindow < 16384 {\n\t\t\t\treturn nil, errors.New(\"MaxConnectionReceiveWindow must be at least 16384\")\n\t\t\t}\n\t\t\tif c.FinalMask.QuicParams.MaxIdleTimeout != 0 && (c.FinalMask.QuicParams.MaxIdleTimeout < 4 || c.FinalMask.QuicParams.MaxIdleTimeout > 120) {\n\t\t\t\treturn nil, errors.New(\"MaxIdleTimeout must be between 4 and 120\")\n\t\t\t}\n\t\t\tif c.FinalMask.QuicParams.KeepAlivePeriod != 0 && (c.FinalMask.QuicParams.KeepAlivePeriod < 2 || c.FinalMask.QuicParams.KeepAlivePeriod > 60) {\n\t\t\t\treturn nil, errors.New(\"KeepAlivePeriod must be between 2 and 60\")\n\t\t\t}\n\t\t\tif c.FinalMask.QuicParams.MaxIncomingStreams != 0 && c.FinalMask.QuicParams.MaxIncomingStreams < 8 {\n\t\t\t\treturn nil, errors.New(\"MaxIncomingStreams must be at least 8\")\n\t\t\t}\n\n\t\t\tif c.FinalMask.QuicParams.Debug {\n\t\t\t\tos.Setenv(\"HYSTERIA_BBR_DEBUG\", \"true\")\n\t\t\t\tos.Setenv(\"HYSTERIA_BRUTAL_DEBUG\", \"true\")\n\t\t\t}\n\n\t\t\tconfig.QuicParams = &internet.QuicParams{\n\t\t\t\tCongestion: c.FinalMask.QuicParams.Congestion,\n\t\t\t\tBbrProfile: profile,\n\t\t\t\tBrutalUp:   up,\n\t\t\t\tBrutalDown: down,\n\t\t\t\tUdpHop: &internet.UdpHop{\n\t\t\t\t\tPorts:       c.FinalMask.QuicParams.UdpHop.PortList.Build().Ports(),\n\t\t\t\t\tIntervalMin: int64(c.FinalMask.QuicParams.UdpHop.Interval.From),","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_internet.go#L258-L294","documentation":"Range check on finalMask.quicParams.keepAlivePeriod: if set (non-zero) it must be between 2 and 60 inclusive (seconds). This guards against keepalive intervals so short they flood the link or so long they fail to keep NAT mappings alive.","triggerScenarios":"\"quicParams\": { \"keepAlivePeriod\": 1 } or \"keepAlivePeriod\": 90 }.","commonSituations":"Sub-second values entered as milliseconds; syncing keepAlive with maxIdleTimeout incorrectly (keepAlive should be well below idle timeout); copying wireguard-style persistent-keepalive values.","solutions":["Set keepAlivePeriod in [2, 60] seconds (e.g. 15 or 30).","Or leave it unset for the default.","Ensure keepAlivePeriod < maxIdleTimeout so pings arrive before idle disconnect."],"exampleFix":"// before\n\"quicParams\": { \"keepAlivePeriod\": 1 }\n// after\n\"quicParams\": { \"keepAlivePeriod\": 15 }","handlingStrategy":"validation","validationCode":"func keepAlivePeriodOK(qp map[string]any) bool {\n    v, ok := qp[\"keepAlivePeriod\"].(float64)\n    return !ok || v == 0 || (v >= 2 && v <= 60)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use seconds in [2, 60]; 15-30 is typical behind NAT.","Do not enter milliseconds (e.g. 15000 fails as > 60).","Pair keepAlivePeriod with a larger maxIdleTimeout."],"tags":["go","xray","config","quic","keepalive","validation"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}