micro/go-micro · error

missing service port

Error message

missing service port

What it means

NewMDNSService requires a non-zero port because an mDNS SRV record pointing at port 0 is meaningless for service discovery. The sanity check rejects port == 0 before any records are built.

Source

Thrown at internal/util/mdns/zone.go:73

//
// If domain, hostName, or ips is set to the zero value, then a default value
// will be inferred from the operating system.
//
// TODO(reddaly): This interface may need to change to account for "unique
// record" conflict rules of the mDNS protocol.  Upon startup, the server should
// check to ensure that the instance name does not conflict with other instance
// names, and, if required, select a new name.  There may also be conflicting
// hostName A/AAAA records.
func NewMDNSService(instance, service, domain, hostName string, port int, ips []net.IP, txt []string) (*MDNSService, error) {
	// Sanity check inputs
	if instance == "" {
		return nil, fmt.Errorf("missing service instance name")
	}
	if service == "" {
		return nil, fmt.Errorf("missing service name")
	}
	if port == 0 {
		return nil, fmt.Errorf("missing service port")
	}

	// Set default domain
	if domain == "" {
		domain = "local."
	}
	if err := validateFQDN(domain); err != nil {
		return nil, fmt.Errorf("domain %q is not a fully-qualified domain name: %v", domain, err)
	}

	// Get host information if no host is specified.
	if hostName == "" {
		var err error
		hostName, err = os.Hostname()
		if err != nil {
			return nil, fmt.Errorf("could not determine host: %v", err)
		}
		hostName = fmt.Sprintf("%s.", hostName)

View on GitHub (pinned to 24529f1404)

Solutions

  1. Start your listener first, then register with the actual bound port (e.g. from listener.Addr().(*net.TCPAddr).Port)
  2. Validate that the port is in 1–65535 before calling NewMDNSService
  3. Fix config parsing so the port field is required and populated

Example fix

// before
ln, _ := net.Listen("tcp", ":0")
svc, err := NewMDNSService("myapp", "_http._tcp", "", "", 0, ips, nil) // forgot to use ln port
// after
port := ln.Addr().(*net.TCPAddr).Port
svc, err := NewMDNSService("myapp", "_http._tcp", "", "", port, ips, nil)
Defensive patterns

Strategy: validation

Validate before calling

if port <= 0 || port > 65535 {
	return errors.New("service port must be a positive number in 1-65535; start the listener before registering")
}

Type guard

func hasValidPort(port int) bool { return port > 0 && port <= 65535 }

Try / catch

svc, err := NewMDNSService(instance, service, domain, hostName, port, ips, txt)
if err != nil {
	if strings.Contains(err.Error(), "missing service port") {
		return fmt.Errorf("register the service after the listener is bound to a real port: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling NewMDNSService(instance, service, domain, hostName, 0, ips, txt) — e.g. the listener's port was not yet known (server not started) or an uninitialized int variable was passed.

Common situations: Registering the service before starting the HTTP/TCP listener so the resolved port is still 0; a config parser leaving port unset; pointer dereference or map lookup returning the zero value.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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