Observe DNS
Observe a requirement through public DNS, provider readback, or both without collapsing propagation, mismatch, and transport failure into a Boolean.
Verification.observe is DomainKit’s only DNS observation operation. Choose evidence sources based
on the question your product is asking.
Observe public DNS
Public DNS is enabled by default:
import { Effect } from "effect";
import { Verification } from "domainkit";
const result = await Effect.runPromise(Verification.observe({ record }));
The default resolver pool queries Cloudflare and Google concurrently with RFC wire-format DNS over
HTTPS. The default AnyMatch policy treats one matching resolver as sufficient.
Observe the authoritative provider
Provider readback asks whether the connected account currently contains the desired record:
const result = await Verification.observe({
provider: Verification.Provider.Enabled({ zone }),
publicDns: Verification.PublicDns.Disabled(),
record,
}).pipe(Effect.provideService(DnsProvider.Service, provider), Effect.runPromise);
This is useful immediately after apply, but it does not prove that public resolvers can answer with the record.
Require both sources
Enable both sources when your workflow requires provider state and public propagation:
const result = await Verification.observe({
provider: Verification.Provider.Enabled({ zone }),
publicDns: Verification.PublicDns.Enabled({}),
record,
}).pipe(Effect.provideService(DnsProvider.Service, provider), Effect.runPromise);
The aggregate is Verified only when every requested source matches.
Handle every outcome
switch (result._tag) {
case "Verified":
break;
case "Pending":
break;
case "Mismatch":
break;
case "Unavailable":
break;
case "NotObserved":
break;
}
Pendingmeans a requested source has not observed the desired record yet.Mismatchmeans observed DNS differs from the requirement.Unavailablemeans the requested observation could not produce trustworthy evidence.NotObservedmeans no evidence source was requested.Verifiedmeans every requested source matched.
Do not turn Unavailable into Pending: retrying a timeout and waiting for propagation are
different product experiences.
Choose a resolver policy
Provide a custom DnsResolverPool.Service when your reliability model needs:
AnyMatch— one resolver match is sufficient;AllMatch— every configured resolver must match;Quorum({ minimum })— at least the selected number must match.
Each public-DNS result preserves the named answer, no-data response, timeout, or failure from every resolver so the host can diagnose disagreement.
Keep product state in the host
DNS observation answers a DNS question. It does not replace certificate issuance, email-provider readiness, application verification, background polling, or your onboarding state machine. Map the tagged evidence into that host-owned lifecycle.