{"record":{"id":"84b50380e5760e35","repo":"XTLS/Xray-core","slug":"invalid-mkcp-tti","errorCode":null,"errorMessage":"invalid mKCP TTI: ","messagePattern":"invalid mKCP TTI: ","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_method.go","lineNumber":566,"sourceCode":"\t}\n\tif c.UpCap != nil {\n\t\tconfig.UplinkCapacity = *c.UpCap\n\t}\n\tif c.DownCap != nil {\n\t\tconfig.DownlinkCapacity = *c.DownCap\n\t}\n\tif c.CwndMultiplier != nil {\n\t\tconfig.CwndMultiplier = *c.CwndMultiplier\n\t}\n\tif c.MaxSendingWindow != nil {\n\t\tconfig.MaxSendingWindow = *c.MaxSendingWindow\n\t}\n\n\tif config.Mtu < 21 {\n\t\treturn nil, errors.New(\"Mtu must be at least 21\").AtError()\n\t}\n\tif config.Tti < 10 || config.Tti > 1000 {\n\t\treturn nil, errors.New(\"invalid mKCP TTI: \", c.Tti).AtError()\n\t}\n\tif config.CwndMultiplier < 1 {\n\t\treturn nil, errors.New(\"CwndMultiplier must be at least 1\").AtError()\n\t}\n\tif config.GetSendingBufferSize() == 0 {\n\t\treturn nil, errors.New(\"MaxSendingWindow must be >= Mtu\").AtError()\n\t}\n\n\treturn config, nil\n}\n\ntype GRPCConfig struct {\n\tAuthority           string `json:\"authority\"`\n\tServiceName         string `json:\"serviceName\"`\n\tMultiMode           bool   `json:\"multiMode\"`\n\tIdleTimeout         int32  `json:\"idle_timeout\"`\n\tHealthCheckTimeout  int32  `json:\"health_check_timeout\"`\n\tPermitWithoutStream bool   `json:\"permit_without_stream\"`","sourceCodeStart":548,"sourceCodeEnd":584,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_method.go#L548-L584","documentation":"Thrown by KCPConfig.Build() when the mKCP TTI (transmission time interval, in milliseconds) is outside the accepted 10-1000 range. TTI controls how often mKCP flushes packets; values below 10 ms waste CPU and values above 1000 ms stall the link, so the builder rejects both. The offending value is included in the message.","triggerScenarios":"Setting kcpSettings.tti to something like 5 or 2000 in the JSON config. Note there is no lower-bound protection for the zero value if the field is absent only when the default is applied; an explicitly bad value always trips this.","commonSituations":"Users copying tti from old docs suggesting aggressive values (e.g. 1ms 'low latency' tweaks), or fat-fingered values like 10000.","solutions":["Set tti between 10 and 1000 inclusive (10, 20, 30, 40, 50 are the conventional choices).","Remove the tti field to use the default (50)."],"exampleFix":"// before\n\"kcpSettings\": { \"mtu\": 1350, \"tti\": 5000 }\n// after\n\"kcpSettings\": { \"mtu\": 1350, \"tti\": 50 }","handlingStrategy":"validation","validationCode":"if kcp.Tti != 0 && (kcp.Tti < 10 || kcp.Tti > 1000) {\n    return fmt.Errorf(\"mKCP tti %d outside 10-1000\", kcp.Tti)\n}","typeGuard":null,"tryCatchPattern":"if _, err := kcpCfg.Build(); err != nil && strings.HasPrefix(err.Error(), \"invalid mKCP TTI\") {\n    return fmt.Errorf(\"fix tti (10-1000 ms): %w\", err)\n}","preventionTips":["Offer users a fixed set of tti presets (10/20/30/40/50) instead of free input.","Range-check tti wherever configs are edited programmatically."],"tags":["config","mkcp","transport","validation","go"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}