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 in serviceMap, but the method part of "Service.Method" has no entry in svc.method. Methods are only registered if they are exported and match the required signature (two args, second a pointer, one error return), so a missing or non-conforming method yields this error.

Source

Thrown at gee-rpc/day5-http-debug/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. Fix the method name string to match the exported method exactly (case-sensitive)
  2. Make the method exported and give it the signature func (t *T) M(args ArgsType, reply *ReplyType) error so Register publishes it
  3. Check server logs at startup — Register skips non-conforming methods; also ensure Register's returned error is not ignored

Example fix

// before
func (s *DemoService) div(args Args, reply *int) error { ... } // unexported, never registered
// after
func (s *DemoService) Div(args Args, reply *int) error { ... } // exported, matches required signature
Defensive patterns

Strategy: validation

Validate before calling

// at startup, verify method registration succeeded
if err := srv.Register(new(DemoService)); err != nil {
    log.Fatalf("register DemoService failed: %v", err)
}
// plus a startup self-check
func assertMethods(svc string, methods ...string) {
    for _, m := range methods {
        if !hasExportedMethod(new(DemoService), m) {
            log.Fatalf("%s.%s is missing or not exported", svc, m)
        }
    }
}

Try / catch

err := client.Call("DemoService.Div", args, reply)
if err != nil && strings.Contains(err.Error(), "can't find method") {
    return fmt.Errorf("method Div is not registered (check export and signature: func (t *T) M(args A, reply *R) error): %w", err)
}

Prevention

When it happens

Trigger: Call("Foo.Bar") where Foo is registered but Bar does not exist, Bar is unexported (lowercase), or Bar exists but fails the signature check during registration and was therefore never added to the method table.

Common situations: Typos in the method name, renaming a method after registration, calling a method that is exported in one version but not another, or a method with the wrong signature (e.g. value second arg or no error return) that Register silently skipped.

Related errors


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