micro/go-micro · error

domain %q is not a fully-qualified domain name: %v

Error message

domain %q is not a fully-qualified domain name: %v

What it means

After defaulting an empty domain to "local.", NewMDNSService validates the domain with validateFQDN; if the domain is non-empty but not a valid FQDN (missing trailing dot), this wrapped error is returned, embedding the validation cause (%v).

Source

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

// 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)
	}
	if err := validateFQDN(hostName); err != nil {
		return nil, fmt.Errorf("hostName %q is not a fully-qualified domain name: %v", hostName, err)
	}

	if len(ips) == 0 {
		var err error
		ips, err = net.LookupIP(trimDot(hostName))

View on GitHub (pinned to 24529f1404)

Solutions

  1. Append the trailing dot: domain = domain + "." before calling NewMDNSService
  2. Use "local." or leave domain empty so the default applies
  3. Pre-validate with the same rule (non-empty, ends in '.') and normalize in config loading

Example fix

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

Strategy: validation

Validate before calling

func normalizeDomain(d string) string {
	if d == "" { return "local." }
	if !strings.HasSuffix(d, ".") { return d + "." }
	return d
}
// domain = normalizeDomain(cfg.Domain)

Type guard

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

Try / catch

svc, err := NewMDNSService(instance, service, domain, hostName, port, ips, txt)
if err != nil {
	if strings.Contains(err.Error(), "is not a fully-qualified domain name") {
		return fmt.Errorf("fix the configured mDNS domain (must end in '.') : %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: NewMDNSService(instance, service, "local", hostName, port, ips, txt) or any domain lacking the trailing period; also any validateFQDN failure like an empty domain string that wasn't defaulted.

Common situations: Configured search domains copied from resolv.conf without trailing dots; users writing "mycompany.local" in YAML/ENV config; case where the domain variable was reassigned after the defaulting branch.

Related errors


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