# DNS monitors

A DNS monitor asks a resolver for one record of a domain name, for example the `A` record of `example.com`. The check passes when the record exists and, if you set expected values, the answer matches them. Use it to find DNS mistakes, expired zones and records that someone changed.

## Add a DNS monitor

1. In the sidebar, select **Monitors**.
2. Select **Create monitor**.
3. Under **Type**, select **DNS**.
4. In **Target**, enter the domain name, for example `example.com` or `_dmarc.example.com`.
5. Under **Record**, select the record type.
6. In **Expected values**, enter the values the answer must have, one per line. This is optional.
7. Select **Create and start**.

## What a check does

1. The Spectate checker sends a query for the record type over UDP. If the answer is truncated, it asks again over TCP.
2. It reads the records of that type from the answer.
3. If the monitor has expected values, it compares them with the answer.

The check fails if any of these is true:

- The response code is not `NOERROR`, for example `NXDOMAIN` or `SERVFAIL`. The error is `dns rcode NXDOMAIN`.
- The answer has no records of the type. The error is `no A records for example.com`.
- The answer does not match the expected values.
- The query takes longer than **Timeout**.

## Record types

| Record | Value format in the answer | Example |
|---|---|---|
| `A` | IPv4 address | `203.0.113.10` |
| `AAAA` | IPv6 address | `2001:db8::10` |
| `CNAME` | Host name | `target.example.net` |
| `MX` | Preference and host | `10 mx.example.com` |
| `NS` | Host name | `ns1.example.net` |
| `TXT` | The text, with the strings joined | `v=spf1 include:_spf.example.com ~all` |
| `CAA` | Flag, tag and value | `0 issue "letsencrypt.org"` |
| `SOA` | Primary name server, mailbox and serial | `ns1.example.net hostmaster.example.com 2026102201` |

Enter expected values in the same format. The default record type is `A`.

## Expected values and matching

**Match** decides how Spectate compares the answer with **Expected values**:

| **Match** | API value | The check passes when |
|---|---|---|
| **Answer contains every value** | `contains` | Every expected value is in the answer. The answer can have more values. |
| **Answer is exactly these values** | `exact` | The answer has the expected values and no others, in any order. |

The comparison ignores upper and lower case and a dot at the end of a name. Quotes around a `TXT` value are optional. You can enter up to 20 values, each up to 512 characters. Without expected values, any answer with at least one record of the type passes.

## Resolver

By default, the checker asks its own resolver. You can change this in the **DNS query** section of the settings:

- **Resolver**: ask a public resolver, as an IP address with an optional port, for example `1.1.1.1` or `9.9.9.9:53`.
- **Ask the authoritative nameservers**: find the name servers of the zone and ask one of them directly. The answer skips resolver caches, so you see a change as soon as the zone publishes it.

With **Ask the authoritative nameservers** on, **Resolver** is not used. Spectate does not query private or reserved addresses.

## Alert when the answer changes

Under **Alerting**, turn on **DNS answer changes** to get an alert when the answer is different from the answer of the previous check. Spectate fires the alert even when the new answer still matches the expected values.

The alert has the severity `low` and the title "DNS records changed for NAME". It shows the old and the new answer. This alert does not resolve on its own. While it fires, later changes do not fire a second alert. Resolve it on the alert page after you check the change.

## Settings reference

| Dashboard label | API field | Default |
|---|---|---|
| **Target** | `uri` | |
| **Record** or **Record type** | `advanced_settings.dns_record_type` | `A` |
| **Expected values** | `advanced_settings.dns_expected_values` | None |
| **Match** | `advanced_settings.dns_match` | `contains` |
| **Resolver** | `advanced_settings.dns_resolver` | The checker's resolver |
| **Ask the authoritative nameservers** | `advanced_settings.dns_authoritative` | Off |
| **DNS answer changes** | `advanced_settings.dns_alert_on_change` | Off |
