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 inputsView on GitHub (pinned to 24529f1404)
Solutions
- Append a trailing period to the value: "myhost.local." or domain + "."
- Normalize inputs in a helper before calling NewMDNSService
- 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
- Always normalize DNS names to end with '.' at config-parse time
- Never copy hostnames straight from /etc/hostname or shell output without appending the dot
- Add a unit test asserting all configured mDNS names pass isFQDN
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
- domain %q is not a fully-qualified domain name: %v
- FQDN must not be blank
- hostName %q is not a fully-qualified domain name: %v
- push callback host %q: %w
- mdns: received query with non-zero Opcode %v: %v
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/3f3c3b45d6d1c91b.
Report an issue: GitHub.