This site is not affiliated with or endorsed by Cloudflare, Inc. It showcases deployable experiments across most Cloudflare products.
Network & Monitoring

URL DNS Lookup

DNS lookup for any URL's hostname via Cloudflare DNS-over-HTTPS (1.1.1.1) - A, AAAA, MX, TXT, and more from a Worker

Retrieve all DNS record types for any URL's hostname using Cloudflare's DNS over HTTPS (DoH) API.

API Reference

GET /dns

Extracts the hostname from the provided URL and returns all available DNS records.

Prop

Type

Example Request

curl "https://your-worker.workers.dev/dns?url=https://www.cloudflare.com/page"

Success Response

hostname string

The extracted hostname that was looked up

records object

DNS records grouped by type. Only record types that exist for the hostname are included.

A array

IPv4 address records

AAAA array

IPv6 address records

CNAME array

Canonical name records

MX array

Mail exchange records

NS array

Name server records

TXT array

Text records

SOA array

Start of authority records

CAA array

Certification authority authorization records

Each DNS record contains:

name string

The domain name for this record

type string

The DNS record type (A, AAAA, CNAME, etc.)

ttl number

Time to live in seconds

data string

The record data (IP address, hostname, etc.)

{
  "hostname": "example.com",
  "records": {
    "A": [
      {
        "name": "example.com",
        "type": "A",
        "ttl": 1726,
        "data": "93.184.220.34"
      }
    ],
    "AAAA": [
      {
        "name": "example.com",
        "type": "AAAA",
        "ttl": 1726,
        "data": "2606:2800:220:1:248:1893:25c8:1946"
      }
    ],
    "NS": [
      {
        "name": "example.com",
        "type": "NS",
        "ttl": 172800,
        "data": "a.iana-servers.net."
      }
    ]
  }
}

Error Response

{
  "error": "Missing or invalid query parameter: url",
  "code": "INVALID_URL"
}

Error Codes

  • 400 - Missing or invalid url parameter (not http/https)
  • 502 - DNS lookup failed (DoH timeout or error)

Supported Record Types

The API queries for the following DNS record types:

  • A - IPv4 addresses
  • AAAA - IPv6 addresses
  • CNAME - Canonical names
  • MX - Mail exchange servers
  • NS - Name servers
  • TXT - Text records
  • SOA - Start of authority
  • CAA - Certificate authority authorization

Implementation Details

  • Uses Cloudflare's public DNS over HTTPS (DoH) API
  • Queries all record types in parallel for fast responses
  • Stateless - no database or KV storage required
  • Timeout protection on DoH requests

Use Cases

  • Resolve DNS records for the hostname extracted from any URL
  • Debug DNS configuration during deployments or migrations
  • Build diagnostic tools without running dig locally
  • Verify mail (MX), certificate (CAA), or CDN (CNAME) records from the edge

Limitations

  • Uses the hostname only; URL path and query string are ignored
  • Queries a fixed set of record types; no PTR or SRV in this experiment
  • DoH timeout if upstream DNS is slow or unreachable
  • Results reflect public DNS; may differ from resolver-specific or split-horizon views

Use in your project

Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/url-dns-lookup.

DependenciesNoneBindingsNonePlatformFetch API
import type { DnsLookupResponse, DohResponse, DnsRecord } from "../types/dns";import { DOH_BASE, DNS_RECORD_TYPES, DOH_TIMEOUT_MS } from "../constants/defaults";const RECORD_TYPE_NAMES: Record<number, string> = {  1: "A",  5: "CNAME",  6: "SOA",  15: "MX",  16: "TXT",  28: "AAAA",  2: "NS",  257: "CAA",};async function queryDoh(hostname: string, type: string): Promise<DohResponse | null> {  const url = `${DOH_BASE}?name=${encodeURIComponent(hostname)}&type=${type}`;  const controller = new AbortController();  const timeout = setTimeout(() => controller.abort(), DOH_TIMEOUT_MS);  try {    const res = await fetch(url, {      headers: { Accept: "application/dns-json" },      signal: controller.signal,    });    clearTimeout(timeout);    if (!res.ok) return null;    const json = (await res.json()) as DohResponse;    return json;  } catch {    clearTimeout(timeout);    return null;  }}function toRecord(doh: { name: string; type: number; TTL: number; data: string }): DnsRecord {  const typeName = RECORD_TYPE_NAMES[doh.type] ?? `TYPE${doh.type}`;  return {    name: doh.name.replace(/\.$/, ""),    type: typeName,    ttl: doh.TTL,    data: doh.data,  };}/** * Fetches all DNS record types for the given hostname via Cloudflare DoH. */export async function lookupDns(hostname: string): Promise<DnsLookupResponse> {  const records: DnsLookupResponse["records"] = {};  const results = await Promise.all(    DNS_RECORD_TYPES.map(async (type) => {      const resp = await queryDoh(hostname, type);      return { type, resp };    })  );  for (const { type, resp } of results) {    if (resp?.Status === 0 && resp.Answer && resp.Answer.length > 0) {      const list = resp.Answer.map(toRecord);      records[type as keyof typeof records] = list;    }  }  return { hostname, records };}

Deployment

Click the deploy button

Deploy to Cloudflare Workers

Deploy

Follow the deployment wizard to deploy the Worker to your Cloudflare account. No additional configuration or bindings required.

Test your deployment

curl "https://your-worker.workers.dev/dns?url=https://www.cloudflare.com"

Local Development

cd apps/experiments/url-dns-lookup
npm install
npm run dev

Test locally:

curl "http://localhost:8787/dns?url=https://www.cloudflare.com"

Cloudflare Features Used

On this page