geektutu/7days-golang · error

rpc server: can't find method

Error message

rpc server: can't find method 

What it means

The service was found but the method name portion of ServiceMethod has no entry in svc.method, meaning the registered receiver has no exported method with that name and a valid RPC signature. Only suitable methods (exported, two args with pointer second arg, one error return) are indexed.

Source

Thrown at gee-rpc/day7-registry/server.go:128

	return &h, nil
}

func (server *Server) findService(serviceMethod string) (svc *service, mtype *methodType, err error) {
	dot := strings.LastIndex(serviceMethod, ".")
	if dot < 0 {
		err = errors.New("rpc server: service/method request ill-formed: " + serviceMethod)
		return
	}
	serviceName, methodName := serviceMethod[:dot], serviceMethod[dot+1:]
	svci, ok := server.serviceMap.Load(serviceName)
	if !ok {
		err = errors.New("rpc server: can't find service " + serviceName)
		return
	}
	svc = svci.(*service)
	mtype = svc.method[methodName]
	if mtype == nil {
		err = errors.New("rpc server: can't find method " + methodName)
	}
	return
}

func (server *Server) readRequest(cc codec.Codec) (*request, error) {
	h, err := server.readRequestHeader(cc)
	if err != nil {
		return nil, err
	}
	req := &request{h: h}
	req.svc, req.mtype, err = server.findService(h.ServiceMethod)
	if err != nil {
		return req, err
	}
	req.argv = req.mtype.newArgv()
	req.replyv = req.mtype.newReplyv()

	// make sure that argvi is a pointer, ReadBody need a pointer as parameter

View on GitHub (pinned to cf36443821)

Solutions

  1. Verify the method exists on the registered receiver with exactly that exported name
  2. Make sure the method matches the required signature: method(ctx context.Context or not, req T, reply *R) error — two args, second a pointer, one error return
  3. Check server-side registration logs/validMethod filtering; rename the client call to match the actual method
  4. Confirm the same struct type is registered as the one defining the method (pointer vs value receiver naming)

Example fix

// before
xf.Call(ctx, "Foo.sum", req, &reply) // unexported, not registered
// after
func (f *Foo) Sum(args *Args, reply *int) error { ... }
xf.Call(ctx, "Foo.Sum", req, &reply)
Defensive patterns

Strategy: validation

Validate before calling

// enforce the RPC method signature at compile time
var _ = func(f *Foo) { _ = f.Sum } // and ensure:
// func (f *Foo) Sum(args *Args, reply *int) error
// exported, two args, second a pointer, returns error

Try / catch

err := client.Call("Foo.Sum", args, &reply)
if err != nil && strings.Contains(err.Error(), "can't find method") {
    log.Printf("method not registered (check name/spelling/signature): %v", err)
}

Prevention

When it happens

Trigger: Calling "Foo.Bar" where Foo is registered but Bar is not an exported method, is unexported (bar), has an unsuitable signature so Register skipped it, or the method name is misspelled.

Common situations: Renaming/refactoring a method without updating clients; adding a method but forgetting the RPC signature rules so it is silently not registered; case sensitivity mistakes ("sum" vs "Sum").

Related errors


AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03). Data as JSON: /api/errors/e5505179c8a167c6. Report an issue: GitHub.