{"record":{"id":"d057c426476110b6","repo":"XTLS/Xray-core","slug":"failed-to-build-grpc-config","errorCode":null,"errorMessage":"Failed to build gRPC config.","messagePattern":"Failed to build gRPC config\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_internet.go","lineNumber":158,"sourceCode":"\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"splithttp\",\n\t\t\tSettings:     serial.ToTypedMessage(hs),\n\t\t})\n\t}\n\tif c.KCPSettings != nil {\n\t\tts, err := c.KCPSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"Failed to build mKCP config.\").Base(err)\n\t\t}\n\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()","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_internet.go#L140-L176","documentation":"Wrapper thrown when streamSettings contains grpcSettings whose Build() fails. The underlying gRPC error is chained with .Base(err); typical causes are an empty or malformed serviceName or multiMode incompatibilities. The detail lives in the base error.","triggerScenarios":"grpcSettings with a missing 'serviceName', a serviceName containing invalid path characters, or stale multiMode configs on a fork that changed gRPC behavior.","commonSituations":"Omitting serviceName when adding gRPC transport; copying serviceName with trailing whitespace or slashes from tutorials.","solutions":["Inspect the base error for the exact gRPC field.","Set a valid non-empty serviceName (e.g. \"MyService\").","Remove deprecated multiMode/userLevel extras and retest."],"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 gRPC config\") {\n        return fmt.Errorf(\"grpc settings invalid: %w\", errors.Unwrap(err))\n    }\n}","preventionTips":["Always set a non-empty serviceName for gRPC transports.","Trim whitespace from copied service names.","Drop multiMode and other legacy flags when migrating."],"tags":["go","xray","config","grpc","transport","error-chaining"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}