---
title: Observe DNS
description: Observe a requirement through public DNS, provider readback, or both without collapsing propagation, mismatch, and transport failure into a Boolean.
seo:
  title: Observe public DNS and provider evidence
---

`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:

```ts
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:

```ts
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:

```ts
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

```ts
switch (result._tag) {
  case "Verified":
    break;
  case "Pending":
    break;
  case "Mismatch":
    break;
  case "Unavailable":
    break;
  case "NotObserved":
    break;
}
```

- `Pending` means a requested source has not observed the desired record yet.
- `Mismatch` means observed DNS differs from the requirement.
- `Unavailable` means the requested observation could not produce trustworthy evidence.
- `NotObserved` means no evidence source was requested.
- `Verified` means 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.

## Related documentation

- [How DomainKit treats observation evidence](/docs/core/verification)
- [Verification API reference](/docs/reference/core#verification)
- [Troubleshooting observation](/docs/guides/troubleshooting#observation)
