{"record":{"id":"3afa1ddb469aa299","repo":"XTLS/Xray-core","slug":"udpidletimeout-must-be-between-2-and-600","errorCode":null,"errorMessage":"UdpIdleTimeout must be between 2 and 600","messagePattern":"UdpIdleTimeout must be between 2 and 600","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_method.go","lineNumber":784,"sourceCode":"\tUp         *Bandwidth `json:\"up\"`\n\tDown       *Bandwidth `json:\"down\"`\n\tUdpHop     *UdpHop    `json:\"udphop\"`\n\n\tUdpIdleTimeout int64      `json:\"udpIdleTimeout\"`\n\tMasquerade     Masquerade `json:\"masquerade\"`\n}\n\nfunc (c *HysteriaConfig) Build() (proto.Message, error) {\n\tif c.Version != 2 {\n\t\treturn nil, errors.New(\"version != 2\")\n\t}\n\n\tif c.Congestion != nil || c.Up != nil || c.Down != nil || c.UdpHop != nil {\n\t\terrors.LogWarning(context.Background(), \"congestion & up & down & udphop move to finalmask/quicParams\")\n\t}\n\n\tif c.UdpIdleTimeout != 0 && (c.UdpIdleTimeout < 2 || c.UdpIdleTimeout > 600) {\n\t\treturn nil, errors.New(\"UdpIdleTimeout must be between 2 and 600\")\n\t}\n\n\tconfig := &hysteria.Config{}\n\tconfig.Auth = c.Auth\n\tconfig.UdpIdleTimeout = c.UdpIdleTimeout\n\tconfig.MasqType = c.Masquerade.Type\n\tconfig.MasqFile = c.Masquerade.Dir\n\tconfig.MasqUrl = c.Masquerade.Url\n\tconfig.MasqUrlRewriteHost = c.Masquerade.RewriteHost\n\tconfig.MasqUrlInsecure = c.Masquerade.Insecure\n\tconfig.MasqString = c.Masquerade.Content\n\tconfig.MasqStringHeaders = c.Masquerade.Headers\n\tconfig.MasqStringStatusCode = c.Masquerade.StatusCode\n\n\tif config.UdpIdleTimeout == 0 {\n\t\tconfig.UdpIdleTimeout = 60\n\t}\n","sourceCodeStart":766,"sourceCodeEnd":802,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_method.go#L766-L802","documentation":"Thrown by HysteriaConfig.Build() when udpIdleTimeout is non-zero and outside the 2-600 second window. Zero means 'use the default' and is allowed; any explicit value must be at least 2 seconds (below that, UDP sessions flap) and at most 600 seconds (above that, dead NAT mappings cause silent loss).","triggerScenarios":"Setting \"udpIdleTimeout\": 1 or \"udpIdleTimeout\": 900 in the hysteria block.","commonSituations":"Trying to expire UDP sessions aggressively for NAT rebinding, or copying a NAT keepalive value in milliseconds (e.g. 30000) instead of seconds.","solutions":["Set udpIdleTimeout to a value between 2 and 600 (seconds).","Omit the field (or set 0) to use the default."],"exampleFix":"// before\n\"udpIdleTimeout\": 30000\n// after\n\"udpIdleTimeout\": 60","handlingStrategy":"validation","validationCode":"if h.UdpIdleTimeout != 0 && (h.UdpIdleTimeout < 2 || h.UdpIdleTimeout > 600) {\n    return fmt.Errorf(\"udpIdleTimeout %d outside 2-600 seconds\", h.UdpIdleTimeout)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Document the field as seconds with range 2-600; 0/absent means default.","Watch for millisecond values pasted from NAT keepalive settings."],"tags":["config","hysteria","udp","timeout","validation","go"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}