{"record":{"id":"3a3e54597bb8c766","repo":"santifer/career-ops","slug":"dns-resolution-returned-no-addresses-for-hostnam","errorCode":null,"errorMessage":"DNS resolution returned no addresses for ${hostname}","messagePattern":"DNS resolution returned no addresses for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"liveness-browser.mjs","lineNumber":183,"sourceCode":"  const previous = hostResolver;\n  hostResolver = resolver ?? resolveViaDns;\n  dnsCache.clear();\n  return () => {\n    hostResolver = previous;\n    dnsCache.clear();\n  };\n}\n\nasync function resolveDnsCached(hostname) {\n  if (dnsCache.has(hostname)) {\n    const cached = dnsCache.get(hostname);\n    if (cached instanceof Error) throw cached;\n    return cached;\n  }\n  try {\n    const addresses = await hostResolver(hostname);\n    if (addresses.length === 0) {\n      throw new Error(`DNS resolution returned no addresses for ${hostname}`);\n    }\n    dnsCache.set(hostname, addresses);\n    return addresses;\n  } catch (err) {\n    dnsCache.set(hostname, err);\n    throw err;\n  }\n}\n\nasync function validateUrlSecurity(urlString) {\n  const url = new URL(urlString.endsWith('.') ? urlString.slice(0, -1) : urlString);\n  const hostname = url.hostname;\n  const host = normalizeHost(hostname);\n  const addresses = await resolveDnsCached(host);\n  for (const ip of addresses) {\n    const norm = normalizeHost(ip);\n    const mapped = extractMappedIPv4(norm);\n    const candidates = mapped ? [norm, mapped] : [norm];","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/liveness-browser.mjs#L165-L201","documentation":"Thrown by resolveDnsCached() in liveness-browser.mjs when the host resolver returned successfully but with an empty address array — i.e. DNS gave no A/AAAA records for the hostname. The result (or this Error) is cached per-hostname so repeated checks fail fast without hammering DNS. This is a fail-closed network precondition before any HTTP attempt.","triggerScenarios":"A hostname that resolves to zero records: a typo (jobs.example.co vs .com), a recently decommissioned subdomain, a domain with only CNAME/MX but no A/AAAA, or a resolver that returns an empty list on NXDOMAIN-like outcomes. hostResolver returns [] and addresses.length === 0 triggers the throw.","commonSituations":"Stale portal URL in portals.yml pointing at a removed subdomain; company migrated careers site and old hostname no longer resolves; transient DNS misconfiguration on the local resolver; a hostname that only has a CNAME chain the resolver flattened to nothing.","solutions":["Verify the hostname with `dig +short hostname` or `nslookup hostname` from the same machine.","Update the URL in portals.yml / pipeline.md to the current careers subdomain.","If DNS works locally but fails in CI, check the CI resolver and /etc/resolv.conf.","Confirm the hostname has an A or AAAA record, not just MX/NS/TXT."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const { Resolver } = require('dns').promises;\nconst r = new Resolver();\nconst addrs = await r.resolve4(hostname).catch(() => []);\nif (addrs.length === 0) {\n  // skip the liveness check rather than letting resolveDnsCached throw\n  return { result: 'uncertain', reason: 'no DNS records' };\n}","typeGuard":null,"tryCatchPattern":"try {\n  await checkUrlLiveness(page, url);\n} catch (e) {\n  if (e.message.startsWith('DNS resolution returned no addresses')) {\n    // hostname no longer resolves — flag the portal entry as stale\n    markPortalStale(url);\n  } else throw e;\n}","preventionTips":["Keep portal URLs current — prune subdomains that companies have retired.","When adding a portal, verify it resolves with `dig +short` first.","Treat persistent DNS empties as stale-portal signals and surface them in a cleanup report.","Don't conflate this with a network error — empty results mean the hostname has no records."],"tags":["network","dns","liveness","ssrf","validation"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}