geektutu/7days-golang · error

rpc server: service/method request ill-formed:

Error message

rpc server: service/method request ill-formed: 

What it means

Server.findService parses the "ServiceName.MethodName" string sent by the client. This error is returned when the string contains no dot separator, so it cannot be split into a service and method part. The library requires the Go RPC convention of "Service.Method" in every request header.

Source

Thrown at gee-rpc/day6-load-balance/server.go:116

	mtype        *methodType
	svc          *service
}

func (server *Server) readRequestHeader(cc codec.Codec) (*codec.Header, error) {
	var h codec.Header
	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)

View on GitHub (pinned to cf36443821)

Solutions

  1. Pass the full "Service.Method" string to xdial/Client.Call, e.g. "Foo.Sum" instead of "Sum".
  2. Log the incoming serviceMethod on the server to confirm what the client actually sent.
  3. Keep service and method names in shared constants so client and server agree on the format.

Example fix

// before
client.Call(ctx, "Sum", req, reply)
// after
client.Call(ctx, "Foo.Sum", req, reply)
Defensive patterns

Strategy: validation

Validate before calling

if !strings.Contains(serviceMethod, ".") || serviceMethod == "" {
    return fmt.Errorf("serviceMethod must be \"Service.Method\", got %q", serviceMethod)
}

Try / catch

if err := client.Call(ctx, serviceMethod, args, reply); err != nil && strings.Contains(err.Error(), "ill-formed") { /* fix call-site naming */ }

Prevention

When it happens

Trigger: Client calls Call()/Go() with a serviceMethod string lacking a dot, e.g. "Foo" instead of "Foo.Bar", or an empty/whitespace-only method string.

Common situations: Typos in the method path, building the serviceMethod string with concatenation or sprintf that drops the dot, passing just a method name when wrapping the client, or an older client version using a different naming scheme.

Related errors


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