micro/go-micro · error

FQDN must end in period: %s

Error message

FQDN must end in period: %s

What it means

validateFQDN requires the name to end in a trailing '.' (the DNS root marker) as mDNS names are stored as fully-qualified names. If the string is non-empty but lacks the final period, this error is thrown by NewMDNSService when validating domain or hostName.

Source

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

	Domain       string   // If blank, assumes "local"
	HostName     string   // Host machine DNS name (e.g. "mymachine.net.")
	serviceAddr  string   // Fully qualified service address
	instanceAddr string   // Fully qualified instance address
	enumAddr     string   // _services._dns-sd._udp.<domain>
	IPs          []net.IP // IP addresses for the service's host
	TXT          []string // Service TXT records
	Port         int      // Service Port
	TTL          uint32
}

// validateFQDN returns an error if the passed string is not a fully qualified
// hdomain name (more specifically, a hostname).
func validateFQDN(s string) error {
	if len(s) == 0 {
		return fmt.Errorf("FQDN must not be blank")
	}
	if s[len(s)-1] != '.' {
		return fmt.Errorf("FQDN must end in period: %s", s)
	}
	// TODO(reddaly): Perform full validation.

	return nil
}

// NewMDNSService returns a new instance of MDNSService.
//
// 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

View on GitHub (pinned to 24529f1404)

Solutions

  1. Append a trailing period to the value: "myhost.local." or domain + "."
  2. Normalize inputs in a helper before calling NewMDNSService
  3. Fix the config entry so the domain/hostname field includes the trailing dot

Example fix

// before
svc, err := NewMDNSService("myapp", "_http._tcp", "local", "myhost.local", 8080, ips, nil)
// after
svc, err := NewMDNSService("myapp", "_http._tcp", "local.", "myhost.local.", 8080, ips, nil)
Defensive patterns

Strategy: validation

Validate before calling

func ensureFQDN(s string) string {
	if s != "" && !strings.HasSuffix(s, ".") {
		return s + "."
	}
	return s
}
// domain = ensureFQDN(domain); hostName = ensureFQDN(hostName)

Type guard

func isFQDN(s string) bool { return len(s) > 0 && s[len(s)-1] == '.' }

Try / catch

svc, err := NewMDNSService(instance, service, domain, hostName, port, ips, txt)
if err != nil {
	if strings.Contains(err.Error(), "must end in period") {
		return fmt.Errorf("bad config: %w (hint: append a trailing '.')", err)
	}
	return err
}

Prevention

When it happens

Trigger: NewMDNSService called with domain like "local" or hostName like "myhost.local" (no trailing dot), or hostName derived from os.Hostname() — no, that path appends the dot; this fires for user-supplied values without the dot.

Common situations: Copying a hostname from /etc/hostname or a config file where trailing dots are usually omitted; building the domain from environment variables like "MY_DOMAIN=example.local".

Related errors


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