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 part of the name has no entry in svc.method (populated only with suitable exported methods at registration time). findService returns this error when mtype is nil, i.e. the server does not know a RPC-callable method by that name on that service.

Source

Thrown at gee-rpc/day4-timeout/server.go:127

	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. Export the method (capitalize it) and ensure its signature is func (t *T) MethodName(args ArgsType, reply *ReplyType) error
  2. Fix the method name string in the client call to match the registered method exactly
  3. Check the registration-time requirements: exactly two args, second a pointer, one error return; adjust the handler accordingly
  4. Ensure client and server are deployed from compatible code versions

Example fix

// before
func (f *Foo) sum(x, y int) int { return x + y } // not eligible

// after
func (f *Foo) Sum(req SumRequest, reply *SumReply) error {
	reply.Value = req.X + req.Y
	return nil
}
Defensive patterns

Strategy: validation

Validate before calling

// ensure the method is exported and RPC-eligible
m := reflect.TypeOf(Foo{}).MethodByName("Sum")
if !m.IsExported() {
	log.Fatal("Sum must be exported")
}
mtype := m.Type
if mtype.NumIn() != 3 || mtype.NumOut() != 1 || mtype.Out(0) != reflect.TypeOf((*error)(nil)).Elem() {
	log.Fatal("Sum must be func(args, *reply) error")
}

Try / catch

err := client.Call(ctx, "Foo.Sum", args, reply)
if err != nil && strings.Contains(err.Error(), "can't find method") {
	return fmt.Errorf("check method name/signature on server: %w", err)
}

Prevention

When it happens

Trigger: Calling a method that is unexported, has a wrong signature (not func(args T1, reply *T2) error), or simply does not exist on the registered type; client string references a renamed method.

Common situations: Calling "Foo.sum" (lowercase, not exported); calling "Foo.Sum2" after renaming; method has zero return values or wrong arg count so it was skipped at registration; client and server code versions drifted.

Related errors


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