koala73/worldmonitor · error · Error
callbackUrl DNS resolution returned no addresses
Error message
callbackUrl DNS resolution returned no addresses
What it means
assertCallbackUrlRegistrationSafe succeeds in reaching the resolver but the combined A+AAAA result is empty, so registration rejects with 'callbackUrl DNS resolution returned no addresses'. The DoH answer had Status 0 but no records survived the type filter (type 1 for A, type 28 for AAAA) — the name resolves authoritatively yet has no address records.
Source
Thrown at server/worldmonitor/shipping/v2/webhook-shared.ts:132
* keeps this fail-fast check from becoming the only SSRF control.
*/
export async function assertCallbackUrlRegistrationSafe(
callbackUrl: string,
resolveHostname: ResolveHostname = defaultResolveHostname,
): Promise<void> {
const staticError = isBlockedCallbackUrl(callbackUrl);
if (staticError) throw new Error(staticError);
const hostname = new URL(callbackUrl).hostname.toLowerCase();
if (isIpLiteral(hostname)) return;
let resolvedAddresses: string[];
try {
resolvedAddresses = await resolveHostname(hostname);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new Error(`callbackUrl DNS resolution failed: ${message}`);
}
if (!resolvedAddresses.length) throw new Error('callbackUrl DNS resolution returned no addresses');
const blocked = resolvedAddresses.find(isBlockedResolvedAddress);
if (blocked) throw new Error('callbackUrl resolves to a private/reserved address');
}
export async function generateSecret(): Promise<string> {
const bytes = new Uint8Array(32);
crypto.getRandomValues(bytes);
return [...bytes].map(b => b.toString(16).padStart(2, '0')).join('');
}
export function generateSubscriberId(): string {
const bytes = new Uint8Array(12);
crypto.getRandomValues(bytes);
return 'wh_' + [...bytes].map(b => b.toString(16).padStart(2, '0')).join('');
}
export function webhookKey(subscriberId: string): string {
return `webhook:sub:${subscriberId}:v1`;View on GitHub (pinned to eeab0a219f)
Solutions
- Verify the host has at least one A or AAAA record: dig example.com A +short and dig example.com AAAA +short
- Add the missing address record at your DNS provider and wait for propagation before registering
- Double-check you registered the receiver hostname, not a bare or mail-only subdomain
Example fix
// before
await registerWebhook({ callbackUrl: 'https://mail-only.example.com/cb', chokepointIds });
// after
await registerWebhook({ callbackUrl: 'https://hooks.example.com/cb', chokepointIds }); // host has an A record Defensive patterns
Strategy: validation
Validate before calling
const a = await resolve(host, 'A'); const aaaa = await resolve(host, 'AAAA');
if (a.length + aaaa.length === 0) throw new RangeError(`${host} has no A/AAAA records — add one before registering`); Try / catch
catch (e) { if (e?.details?.[0]?.description === 'callbackUrl DNS resolution returned no addresses') { add an A/AAAA record, wait for propagation, re-submit } else throw e; } Prevention
- Confirm the receiver hostname has at least one A or AAAA record before registering
- Do not use mail-only or parked domains as callback hosts
- After creating new DNS records, wait for propagation before webhook registration
When it happens
Trigger: Registering a webhook whose hostname exists in DNS but has no A or AAAA records: a domain with only MX/TXT records, a CNAME chain ending without address records, or answers of other types the filter drops. Also possible during DNS propagation windows right after record creation.
Common situations: Parked domains with no address records; apex CNAME configurations that yield no A; a record created minutes ago not yet propagated; hostnames meant only for email or verification.
Understand the failure class
- DNS resolution errors: ENOTFOUND and getaddrinfo failures — how hostname lookups fail and how to debug them.
Related errors
- DNS ${recordType} lookup failed: HTTP ${response.status}
- DNS ${recordType} lookup failed: status ${data.Status}
- callbackUrl DNS resolution failed: ${message}
- callbackUrl resolves to a private/reserved address
- API key required
AI-assisted analysis of koala73/worldmonitor@eeab0a219f (2026-08-21).
Data as JSON: /api/errors/fece3f71368494bd.
Report an issue: GitHub.