{"record":{"id":"97536e4f89da4794","repo":"geektutu/7days-golang","slug":"rpc-server-service-method-request-ill-formed-97536e","errorCode":null,"errorMessage":"rpc server: service/method request ill-formed: ","messagePattern":"rpc server: service/method request ill-formed: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-rpc/day4-timeout/server.go","lineNumber":115,"sourceCode":"\tmtype        *methodType\n\tsvc          *service\n}\n\nfunc (server *Server) readRequestHeader(cc codec.Codec) (*codec.Header, error) {\n\tvar h codec.Header\n\tif err := cc.ReadHeader(&h); err != nil {\n\t\tif err != io.EOF && err != io.ErrUnexpectedEOF {\n\t\t\tlog.Println(\"rpc server: read header error:\", err)\n\t\t}\n\t\treturn nil, err\n\t}\n\treturn &h, nil\n}\n\nfunc (server *Server) findService(serviceMethod string) (svc *service, mtype *methodType, err error) {\n\tdot := strings.LastIndex(serviceMethod, \".\")\n\tif dot < 0 {\n\t\terr = errors.New(\"rpc server: service/method request ill-formed: \" + serviceMethod)\n\t\treturn\n\t}\n\tserviceName, methodName := serviceMethod[:dot], serviceMethod[dot+1:]\n\tsvci, ok := server.serviceMap.Load(serviceName)\n\tif !ok {\n\t\terr = errors.New(\"rpc server: can't find service \" + serviceName)\n\t\treturn\n\t}\n\tsvc = svci.(*service)\n\tmtype = svc.method[methodName]\n\tif mtype == nil {\n\t\terr = errors.New(\"rpc server: can't find method \" + methodName)\n\t}\n\treturn\n}\n\nfunc (server *Server) readRequest(cc codec.Codec) (*request, error) {\n\th, err := server.readRequestHeader(cc)","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-rpc/day4-timeout/server.go#L97-L133","documentation":"findService parses the service method string of the incoming request header. A well-formed name must contain a dot separating service and method (e.g. \"Foo.Sum\"). If no dot is present the request is ill-formed, and the server rejects it and replies with this error instead of dispatching.","triggerScenarios":"A client sends a request whose ServiceMethod header field has no '.' separator, e.g. \"FooSum\" or an empty string, via Client.Call/Go with a malformed method name.","commonSituations":"Typo in the method name at the call site; building the method string dynamically and dropping the '.'; protocol mismatch where an older client sends a different naming scheme; empty method argument from a config value.","solutions":["Fix the client call site to pass \"ServiceName.MethodName\", e.g. client.Call(ctx, \"Foo.Sum\", ...)","Log/inspect the string echoed in the error message to see the malformed value actually received","Ensure both sides agree on the naming convention for the service registry"],"exampleFix":"// before\nerr := client.Call(ctx, \"FooSum\", args, reply)\n\n// after\nerr := client.Call(ctx, \"Foo.Sum\", args, reply)","handlingStrategy":"validation","validationCode":"// validate the method string before calling\nfunc validMethod(m string) bool {\n\tdot := strings.LastIndex(m, \".\")\n\treturn dot > 0 && dot < len(m)-1\n}\n// if !validMethod(\"Foo.Sum\") { ... }","typeGuard":null,"tryCatchPattern":"err := client.Call(ctx, method, args, reply)\nif err != nil && strings.Contains(err.Error(), \"service/method request ill-formed\") {\n\treturn fmt.Errorf(\"method name %q must be Service.Method\", method)\n}","preventionTips":["Use typed constants for method names instead of free-form strings","Validate \"Service.Method\" shape at config load time","Share method-name constants between client and server packages"],"tags":["rpc","server","request-validation","go"],"backgroundTag":"malformed-method-name","analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}