{"record":{"id":"3c60f7c8914be4c9","repo":"XTLS/Xray-core","slug":"tcpfastopen-only-boolean-and-integer-value-is-acc","errorCode":null,"errorMessage":"tcpFastOpen: only boolean and integer value is acceptable","messagePattern":"tcpFastOpen: only boolean and integer value is acceptable","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_sockopt.go","lineNumber":82,"sourceCode":"\tHappyEyeballsSettings *HappyEyeballsConfig   `json:\"happyEyeballs\"`\n\tTrustedXForwardedFor  []string               `json:\"trustedXForwardedFor\"`\n}\n\n// Build implements Buildable.\nfunc (c *SocketConfig) Build() (*internet.SocketConfig, error) {\n\ttfo := int32(0) // don't invoke setsockopt() for TFO\n\tif c.TFO != nil {\n\t\tswitch v := c.TFO.(type) {\n\t\tcase bool:\n\t\t\tif v {\n\t\t\t\ttfo = 256\n\t\t\t} else {\n\t\t\t\ttfo = -1 // TFO need to be disabled\n\t\t\t}\n\t\tcase float64:\n\t\t\ttfo = int32(math.Min(v, math.MaxInt32))\n\t\tdefault:\n\t\t\treturn nil, errors.New(\"tcpFastOpen: only boolean and integer value is acceptable\")\n\t\t}\n\t}\n\tvar tproxy internet.SocketConfig_TProxyMode\n\tswitch strings.ToLower(c.TProxy) {\n\tcase \"tproxy\":\n\t\ttproxy = internet.SocketConfig_TProxy\n\tcase \"redirect\":\n\t\ttproxy = internet.SocketConfig_Redirect\n\tdefault:\n\t\ttproxy = internet.SocketConfig_Off\n\t}\n\n\tdStrategy := internet.DomainStrategy_AS_IS\n\tswitch strings.ToLower(c.DomainStrategy) {\n\tcase \"asis\", \"\":\n\t\tdStrategy = internet.DomainStrategy_AS_IS\n\tcase \"useip\":\n\t\tdStrategy = internet.DomainStrategy_USE_IP","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_sockopt.go#L64-L100","documentation":"Thrown while building SocketConfig from a 'sockopt' JSON block. The 'tcpFastOpen' (tfo) field only accepts a JSON boolean or a number; after JSON decoding any number arrives as float64, and the type switch only handles bool and float64. Any other JSON type (string, array, object, null-shaped non-nil weirdness) reaches the default branch and this error is returned.","triggerScenarios":"Setting \"sockopt\": { \"tcpFastOpen\": \"true\" } (string instead of bool), \"tcpFastOpen\": [256], or \"tcpFastOpen\": { \"enabled\": true } in any inbound/outbound/streamSettings socket options, then loading the config.","commonSituations":"Copy-pasting a config from a wiki/blog that quoted the value (\"true\" instead of true), or a YAML-to-JSON conversion that turned the bare word true into a string.","solutions":["Change the value to a JSON boolean: \"tcpFastOpen\": true (enable) or false (disable)","Or use an integer queue length: \"tcpFastOpen\": 256","Remove the tcpFastOpen key entirely if TFO behavior is not needed"],"exampleFix":"// before\n\"sockopt\": { \"tcpFastOpen\": \"true\" }\n// after\n\"sockopt\": { \"tcpFastOpen\": true }","handlingStrategy":"validation","validationCode":"// before marshalling config, validate sockopt.tcpFastOpen\nfunc validTFO(v interface{}) bool {\n    switch v.(type) {\n    case bool, float64, int, int64, json.Number:\n        return true\n    }\n    return false\n}\nif raw, ok := sockopt[\"tcpFastOpen\"]; ok && !validTFO(raw) {\n    return fmt.Errorf(\"tcpFastOpen must be bool or number, got %T\", raw)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always emit tcpFastOpen as a JSON boolean from config generators","Validate generated configs with `xray run -test -c config.json` before deploy","Never quote boolean values when hand-editing JSON"],"tags":["config","socket","tcp","tcp-fast-open","json"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}