{"record":{"id":"3f3c3b45d6d1c91b","repo":"micro/go-micro","slug":"fqdn-must-end-in-period-s","errorCode":null,"errorMessage":"FQDN must end in period: %s","messagePattern":"FQDN must end in period: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/util/mdns/zone.go","lineNumber":47,"sourceCode":"\tDomain       string   // If blank, assumes \"local\"\n\tHostName     string   // Host machine DNS name (e.g. \"mymachine.net.\")\n\tserviceAddr  string   // Fully qualified service address\n\tinstanceAddr string   // Fully qualified instance address\n\tenumAddr     string   // _services._dns-sd._udp.<domain>\n\tIPs          []net.IP // IP addresses for the service's host\n\tTXT          []string // Service TXT records\n\tPort         int      // Service Port\n\tTTL          uint32\n}\n\n// validateFQDN returns an error if the passed string is not a fully qualified\n// hdomain name (more specifically, a hostname).\nfunc validateFQDN(s string) error {\n\tif len(s) == 0 {\n\t\treturn fmt.Errorf(\"FQDN must not be blank\")\n\t}\n\tif s[len(s)-1] != '.' {\n\t\treturn fmt.Errorf(\"FQDN must end in period: %s\", s)\n\t}\n\t// TODO(reddaly): Perform full validation.\n\n\treturn nil\n}\n\n// NewMDNSService returns a new instance of MDNSService.\n//\n// If domain, hostName, or ips is set to the zero value, then a default value\n// will be inferred from the operating system.\n//\n// TODO(reddaly): This interface may need to change to account for \"unique\n// record\" conflict rules of the mDNS protocol.  Upon startup, the server should\n// check to ensure that the instance name does not conflict with other instance\n// names, and, if required, select a new name.  There may also be conflicting\n// hostName A/AAAA records.\nfunc NewMDNSService(instance, service, domain, hostName string, port int, ips []net.IP, txt []string) (*MDNSService, error) {\n\t// Sanity check inputs","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/internal/util/mdns/zone.go#L29-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"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\".","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"],"exampleFix":"// before\nsvc, err := NewMDNSService(\"myapp\", \"_http._tcp\", \"local\", \"myhost.local\", 8080, ips, nil)\n// after\nsvc, err := NewMDNSService(\"myapp\", \"_http._tcp\", \"local.\", \"myhost.local.\", 8080, ips, nil)","handlingStrategy":"validation","validationCode":"func ensureFQDN(s string) string {\n\tif s != \"\" && !strings.HasSuffix(s, \".\") {\n\t\treturn s + \".\"\n\t}\n\treturn s\n}\n// domain = ensureFQDN(domain); hostName = ensureFQDN(hostName)","typeGuard":"func isFQDN(s string) bool { return len(s) > 0 && s[len(s)-1] == '.' }","tryCatchPattern":"svc, err := NewMDNSService(instance, service, domain, hostName, port, ips, txt)\nif err != nil {\n\tif strings.Contains(err.Error(), \"must end in period\") {\n\t\treturn fmt.Errorf(\"bad config: %w (hint: append a trailing '.')\", err)\n\t}\n\treturn err\n}","preventionTips":["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"],"tags":["validation","mdns","fqdn","dns"],"backgroundTag":"fqdn-missing-trailing-dot","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}