micro/go-micro · error

rpc.Handle: handler has no name

Error message

rpc.Handle: handler has no name

What it means

Handle was called with a handler whose Name() returns an empty string. The router refuses to register a service with no name because it could never be addressed by an endpoint. This is a registration-time (startup) error, not a request-time error.

Source

Thrown at server/rpc_router.go:461

	}

	return
}

func (router *router) NewHandler(h interface{}, opts ...HandlerOption) Handler {
	return NewRpcHandler(h, opts...)
}

func (router *router) Handle(h Handler) error {
	router.mu.Lock()
	defer router.mu.Unlock()

	if router.serviceMap == nil {
		router.serviceMap = make(map[string]*service)
	}

	if len(h.Name()) == 0 {
		return errors.New("rpc.Handle: handler has no name")
	}

	if !isExported(h.Name()) {
		return errors.New("rpc.Handle: type " + h.Name() + " is not exported")
	}

	rcvr := h.Handler()
	s := new(service)
	s.typ = reflect.TypeOf(rcvr)
	s.rcvr = reflect.ValueOf(rcvr)

	// check name
	if _, present := router.serviceMap[h.Name()]; present {
		return errors.New("rpc.Handle: service already defined: " + h.Name())
	}

	s.name = h.Name()
	s.method = make(map[string]*methodType)

View on GitHub (pinned to 24529f1404)

Solutions

  1. Provide a non-empty name when constructing the handler (option or constructor argument)
  2. Check the config/source of the handler name for missing or empty values
  3. If implementing a custom Handler, return a valid exported name from Name()

Example fix

// before
router.NewHandler(NewCalcService(""))
// after
router.NewHandler(NewCalcService("Calculator"))
Defensive patterns

Strategy: validation

Validate before calling

if h.Name() == "" {
	return errors.New("handler name must be non-empty before calling Handle")
}
router.NewHandler(h)

Try / catch

if err := router.NewHandler(h); err != nil {
	if strings.Contains(err.Error(), "handler has no name") {
		return fmt.Errorf("handler %T missing configured name: %w", h, err)
	}
	return err
}

Prevention

When it happens

Trigger: Constructing a handler wrapper whose name field was never set (e.g. NewHandler with an empty name option), or a custom Handler implementation returning "" from Name().

Common situations: Passing an empty string to a name parameter/option; building handlers dynamically from config where the name key is missing; a custom Handler type forgetting to implement Name().

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/0bec7c7a96a7f12a. Report an issue: GitHub.