{"record":{"id":"f9a55a2c44d5b98b","repo":"grpc/grpc-go","slug":"invalid-method-name-suffix-method-is-missing","errorCode":null,"errorMessage":"invalid method name: suffix /method is missing","messagePattern":"invalid method name: suffix /method is missing","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/grpcutil/method.go","lineNumber":36,"sourceCode":"\npackage grpcutil\n\nimport (\n\t\"errors\"\n\t\"strings\"\n)\n\n// ParseMethod splits service and method from the input. It expects format\n// \"/service/method\".\nfunc ParseMethod(methodName string) (service, method string, _ error) {\n\tif !strings.HasPrefix(methodName, \"/\") {\n\t\treturn \"\", \"\", errors.New(\"invalid method name: should start with /\")\n\t}\n\tmethodName = methodName[1:]\n\n\tpos := strings.LastIndex(methodName, \"/\")\n\tif pos < 0 {\n\t\treturn \"\", \"\", errors.New(\"invalid method name: suffix /method is missing\")\n\t}\n\treturn methodName[:pos], methodName[pos+1:], nil\n}\n\n// baseContentType is the base content-type for gRPC.  This is a valid\n// content-type on its own, but can also include a content-subtype such as\n// \"proto\" as a suffix after \"+\" or \";\".  See\n// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests\n// for more details.\nconst baseContentType = \"application/grpc\"\n\n// ContentSubtype returns the content-subtype for the given content-type.  The\n// given content-type must be a valid content-type that starts with\n// \"application/grpc\". A content-subtype will follow \"application/grpc\" after a\n// \"+\" or \";\". See\n// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for\n// more details.\n//","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/grpcutil/method.go#L18-L54","documentation":"Returned by grpcutil.ParseMethod when the method name starts with '/' but contains no further '/' to separate the service from the method. After stripping the leading slash, the code calls strings.LastIndex looking for '/'; if none is found (pos < 0), the format '/service/method' is not satisfied. This means the string is just '/something' with no method component.","triggerScenarios":"Calling ParseMethod with a string like '/ServiceName' (no trailing '/Method'), or '/ServiceName/' (trailing slash but no method after it). Happens when method paths are truncated, malformed, or constructed incorrectly.","commonSituations":"Proxies or gateways that truncate the gRPC path; incorrect service config method patterns; test fixtures or mocks with incomplete method names; manual path string construction missing the method suffix.","solutions":["Ensure method names include both service and method separated by '/', e.g., '/package.Service/Method'.","Validate the method string has at least two '/' characters before calling ParseMethod.","Check that proxies, load balancers, or service mesh configurations do not truncate the :path header.","Log the full method path to find where truncation occurs."],"exampleFix":"// before\nsvc, method, err := grpcutil.ParseMethod(\"/myapp.UserService\")\n// after\nsvc, method, err := grpcutil.ParseMethod(\"/myapp.UserService/GetUser\")","handlingStrategy":"validation","validationCode":"// Validate method name has both service and method components.\nfunc isValidMethodName(method string) bool {\n    if !strings.HasPrefix(method, \"/\") { return false }\n    rest := method[1:]\n    return strings.Count(rest, \"/\") >= 1 && !strings.HasSuffix(rest, \"/\")\n}\nif !isValidMethodName(method) {\n    return fmt.Errorf(\"method %q must be '/package.Service/Method'\", method)\n}","typeGuard":null,"tryCatchPattern":"svc, method, err := grpcutil.ParseMethod(name)\nif err != nil {\n    log.Printf(\"malformed method name %q: %v\", name, err)\n    return err\n}","preventionTips":["Ensure method names always include '/Service/Method' after the leading slash.","Validate externally-supplied method strings before parsing.","Check that proxies do not truncate the :path header.","Use well-formed method names from gRPC framework rather than manual construction."],"tags":["grpc","method-routing","internal","validation"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}