{"record":{"id":"29b0d431252e626c","repo":"hashicorp/nomad","slug":"error-resolving-bind-address-q-v","errorCode":null,"errorMessage":"Error resolving bind address %q: %v","messagePattern":"Error resolving bind address %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/config.go","lineNumber":2553,"sourceCode":"\tif addr != \"\" {\n\t\t// Default to using manually configured address\n\t\t_, _, err = net.SplitHostPort(addr)\n\t\tif err != nil {\n\t\t\tif !isMissingPort(err) && !isTooManyColons(err) {\n\t\t\t\treturn \"\", fmt.Errorf(\"Error parsing advertise address %q: %v\", addr, err)\n\t\t\t}\n\n\t\t\t// missing port, append the default\n\t\t\treturn normalizeAddrWithPort(addr, defport), nil\n\t\t}\n\n\t\treturn ipaddr.NormalizeAddr(addr), nil\n\t}\n\n\t// Fallback to bind address first, and then try resolving the local hostname\n\tips, err := net.LookupIP(bind)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"Error resolving bind address %q: %v\", bind, err)\n\t}\n\n\t// Return the first non-localhost unicast address\n\tfor _, ip := range ips {\n\t\tif ip.IsLinkLocalUnicast() || ip.IsGlobalUnicast() {\n\t\t\treturn normalizeAddrWithPort(ip.String(), defport), nil\n\t\t}\n\t\tif ip.IsLoopback() {\n\t\t\tif dev {\n\t\t\t\t// loopback is fine for dev mode\n\t\t\t\treturn normalizeAddrWithPort(ip.String(), defport), nil\n\t\t\t}\n\t\t\treturn \"\", fmt.Errorf(\"Defaulting advertise to localhost is unsafe, please set advertise manually\")\n\t\t}\n\t}\n\n\t// Bind is not localhost but not a valid advertise IP, use first private IP\n\taddr, err = listenerutil.ParseSingleIPTemplate(\"{{ GetPrivateIP }}\")","sourceCodeStart":2535,"sourceCodeEnd":2571,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/config.go#L2535-L2571","documentation":"In normalizeAddr, when no explicit address is configured the code falls back to resolving the bind address via net.LookupIP; resolution failure (unresolvable hostname, no network) prevents computing the advertise address and aborts agent startup.","triggerScenarios":"advertise is unset and bind is set to a hostname (or a value like {{ ... }} that resolved to one) that net.LookupIP cannot resolve — no DNS record, /etc/hosts miss, or DNS server unreachable.","commonSituations":"Containers/VMs where the hostname isn't registered in DNS, bind set to a stale hostname after infrastructure changes, or offline/broken resolv.conf during startup.","solutions":["Set advertise explicitly to a routable IP so the bind fallback is never used","Change bind to a literal IP address instead of a hostname","Fix DNS/hosts resolution for the hostname used in bind","Verify /etc/resolv.conf points at a reachable resolver"],"exampleFix":"// before\nbind_addr = \"my-node.internal\" // unresolvable\n// after\nbind_addr = \"0.0.0.0\"\nadvertise_addr = \"10.0.0.5\"","handlingStrategy":"validation","validationCode":"if cfg.Advertise == \"\" && isHostname(cfg.BindAddr) {\n    if ips, err := net.LookupIP(cfg.BindAddr); err != nil || len(ips) == 0 {\n        return fmt.Errorf(\"bind %q not resolvable; set advertise explicitly\", cfg.BindAddr)\n    }\n}","typeGuard":null,"tryCatchPattern":"ips, err := net.LookupIP(bind)\nif err != nil {\n    ip := firstNonLoopbackLocalIP()\n    if ip != nil { return useAdvertise(net.JoinHostPort(ip.String(), port)) }\n    return err\n}","preventionTips":["Set advertise_addr explicitly on every non-dev agent","Prefer literal IPs over hostnames for bind in containers","Ensure hostname resolution works in the target environment","Add DNS checks to node bootstrap scripts"],"tags":["network","dns","consul","advertise-address"],"backgroundTag":"dns-resolution-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}