{"record":{"id":"8b6bf743ed572074","repo":"XTLS/Xray-core","slug":"failed-to-build-websocket-config","errorCode":null,"errorMessage":"Failed to build WebSocket config.","messagePattern":"Failed to build WebSocket config\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_internet.go","lineNumber":168,"sourceCode":"\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"mkcp\",\n\t\t\tSettings:     serial.ToTypedMessage(ts),\n\t\t})\n\t}\n\tif c.GRPCSettings != nil {\n\t\tgs, err := c.GRPCSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"Failed to build gRPC config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"grpc\",\n\t\t\tSettings:     serial.ToTypedMessage(gs),\n\t\t})\n\t}\n\tif c.WSSettings != nil {\n\t\tts, err := c.WSSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"Failed to build WebSocket config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"websocket\",\n\t\t\tSettings:     serial.ToTypedMessage(ts),\n\t\t})\n\t}\n\tif c.HTTPUPGRADESettings != nil {\n\t\ths, err := c.HTTPUPGRADESettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"Failed to build HTTPUpgrade config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"httpupgrade\",\n\t\t\tSettings:     serial.ToTypedMessage(hs),\n\t\t})\n\t}\n\tif c.HysteriaSettings != nil {\n\t\ths, err := c.HysteriaSettings.Build()","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_internet.go#L150-L186","documentation":"Wrapper thrown when streamSettings contains wsSettings whose Build() fails. The concrete WebSocket error (bad path, invalid headers, wrong early-data settings) is chained via .Base(err). Note the websocket transport itself is deprecated in favor of XHTTP, which emits a separate warning before this build is attempted.","triggerScenarios":"wsSettings with a path lacking a leading '/', malformed request headers, or an invalid maxEarlyData/earlyDataHeaderName combination.","commonSituations":"Legacy websocket configs carried forward; path values like \"ws\" instead of \"/ws\"; subscription-generated header maps with non-string values.","solutions":["Inspect the chained base error for the failing WS field.","Normalize path to start with '/' and clean up headers.","Consider migrating to httpupgrade or XHTTP since websocket is deprecated here."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := streamCfg.Build(); err != nil {\n    if strings.Contains(err.Error(), \"Failed to build WebSocket config\") {\n        return fmt.Errorf(\"ws settings invalid: %w\", errors.Unwrap(err))\n    }\n}","preventionTips":["Root every ws path with '/'.","Type-check header maps as map[string]string before serialization.","Plan migration off websocket — it is deprecated in favor of XHTTP here."],"tags":["go","xray","config","websocket","transport","error-chaining"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}