geektutu/7days-golang · error
rpc server: can't find service
Error message
rpc server: can't find service
What it means
The service part of the "Service.Method" request was syntactically valid, but no service with that name is registered in the server's serviceMap. findService fails the Load on serviceMap, meaning the receiver was never published via Register on this server instance.
Source
Thrown at gee-rpc/day6-load-balance/server.go:122
if err := cc.ReadHeader(&h); err != nil {
if err != io.EOF && err != io.ErrUnexpectedEOF {
log.Println("rpc server: read header error:", err)
}
return nil, err
}
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 {View on GitHub (pinned to cf36443821)
Solutions
- Register the receiver on the server: geeRPC.Register(new(Foo)) before serving.
- Verify the registered name matches: GeeRegistry uses the Go type name, so &pkg.Foo{} registers as "Foo".
- If using a registry/load balancer, ensure every reachable server instance registers the requested service.
Example fix
// before (server main) // (nothing registered) // after srv := geeRPC.NewServer() _ = srv.Register(new(Foo)) log.Fatal(srv.Accept(lis))
Defensive patterns
Strategy: validation
Validate before calling
// server side, before Accept
if err := srv.Register(new(Foo)); err != nil { log.Fatalf("register Foo: %v", err) }
// client side, sanity check the name matches the registered Go type
const svc = "Foo" // must equal reflect.TypeOf(Foo{}).Name() Try / catch
if err := client.Call(ctx, "Foo.Sum", args, reply); err != nil && strings.Contains(err.Error(), "can't find service") { log.Fatalf("service not registered on this server: %v", err) } Prevention
- Register every service during server startup and log the registration result.
- Keep service type names identical between client and server packages.
- When using registries/load balancers, verify all instances register the same services.
When it happens
Trigger: Client calls "Foo.Bar" while the server never executed Register(&Foo{}), registered Foo under a different name, or the request reached the wrong server instance (e.g. behind a load balancer where only some instances registered the service).
Common situations: Forgot to call geeRPC.Register in the server main, service struct name differs between packages (Go uses the reflected type name, so an unexported or renamed type registers under a different string), or multiple registry nodes where one has the service and others do not.
Related errors
- rpc: service already defined:
- rpc server: can't find service
- rpc: service already defined:
- rpc: service already defined:
- rpc: service already defined:
AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03).
Data as JSON: /api/errors/60925eb77e3167d5.
Report an issue: GitHub.