Skip to content

Domain expiry checks

A domain expiry check reads your domain’s registration record from its registry and alerts you on what the registry says: how long the registration has left, whether the registry is already holding it, who the sponsoring registrar is, and where the nameservers point.

The API and the dashboard call these DNS checks (monitor_dns, /dns/job/...). The name is historical: the thing monitored is the domain registration.

The check does not query any nameserver, so it cannot confirm that your domain resolves, that an A record points where you expect, or that any resolver answers. For that, use a DNS record monitor (DNS monitor in the dashboard).

  • Any domain you would lose if a renewal silently failed. The usual cause is an expired card on the registrar account, not a forgotten date.
  • Domains you inherited from an agency, a former employee or an acquisition, where nobody is certain who holds the renewal.
  • Domains where a hijack would be expensive. An unannounced registrar or nameserver change is the earliest visible signal of an unauthorized transfer, usually well before the site goes dark.
  • Portfolios. Every monitored domain reports the same three signals, so one alert format covers all of them.

A domain check is paired with an HTTP check. Set monitor_dns: true and Site Qwality provisions one against the registrable domain of the HTTP check’s URL, so https://www.example.com/orders is monitored as example.com.

Once a day, the check reads the registration from the first of three sources that has a record for the name:

  1. Registry RDAP, the registry’s own RDAP service. Always tried first.
  2. Port-43 WHOIS, the registry’s own WHOIS server, when the TLD has no RDAP service or RDAP had no record for this name. RDAP is mandatory for gTLDs but optional for ccTLDs, so many country-code registries run WHOIS only.
  3. A commercial registration database, when neither of the first two produced a record.

The first two are the registry’s own answer; the third catches the long tail. expiry_source on the check names the source that answered. See where the expiry date comes from.

Because the date is the registry’s, your registrar’s control panel may show a date one day earlier. The registry’s date is the one that governs what happens to the domain.

Each run records the expiry date, the registry status codes, the registrar and the nameservers, and alerts on the three signals below through the parent HTTP check’s notification groups.

When the registry publishes no expiry date

Section titled “When the registry publishes no expiry date”

Some registries publish no expiry date to anybody, under any protocol. That is registry policy, and no fallback can route around it. These TLDs are established to publish none:

.am · .at · .be · .de · .eu · .gg · .im · .nl · .no · .nz

A domain on one of these reports current_status: unknown and last_failure_reason: registry_publishes_no_expiry. That is a state, not a broken check: it is not retried, does not clear on its own, and is not an alert. Only the expiry ladder is affected; the registrar and nameserver change alerts run off whatever fields the registry does return.

For these TLDs, enter the renewal date yourself, in the Renewal date field of the HTTP check’s domain registration details or as manual_expiry_date through the API (steps). The normal ladder then runs against it and expiry_source reads manual. Nothing updates a manual date when you renew, so set the new date as part of every renewal, or the ladder will warn about a renewal you already completed and then report the domain as expired.

RungFires whenMessage
90 days90 or fewer days remainexample.com expires in 90 days
60 days60 or fewer days remainexample.com expires in 60 days
30 days30 or fewer days remainexample.com expires in 30 days
7 days7 or fewer days remainexample.com expires in 7 days
LapseThe expiry date is today, or has already passedexample.com expires today, or example.com has expired

Each rung fires once per expiry date.

  • Rungs fire on crossing, not on an exact match. A check that lands at 29 days remaining, having last run at 31, still sends the 30-day warning.
  • A rung already passed when monitoring started does not fire late. Enable a check on a domain with 45 days left and you get the 60-day warning only, not a burst of 90 and 60.
  • A renewal resets the ladder. When the expiry date moves, the record of fired rungs is cleared, so next year’s warnings start from a clean slate.

Every registry publishes a set of EPP status codes on a registration. Most are routine (client transfer prohibited is a lock you want). A few mean the registration is already in trouble, and Site Qwality alerts the first time a domain enters one of them:

Registry stateWhat it meansWhat you should do
auto renew periodThe registration reached its expiry date without being renewed, so the registry renewed it on the registrar’s behalf. The registrar can still cancel that renewal for a refund, typically within 45 days, which deletes the domain.Confirm with your registrar that the renewal was actually paid.
redemption periodThe domain was deleted. It is recoverable, usually for about 30 days and usually for a restoration fee well above the renewal price.Contact your registrar today and ask for a redemption restore.
pending deleteRedemption has ended. The domain drops in about five days and cannot be recovered.It is effectively gone. Prepare for the name to be re-registered by someone else.
pending restoreA restore has been requested but is not complete.Follow it through with the registrar until the state clears.
client hold / server holdThe registrar or the registry has pulled the domain out of the zone. The domain does not resolve for anyone right now.Find out why. This is usually a payment dispute or an abuse complaint.

A status alert fires on the transition into a state, so a domain sitting in auto renew period for its whole 45-day window alerts once. A worse state (auto renew period becoming pending delete) is a new alert.

This is the signal the expiry date cannot give you. When a registration passes its expiry date unrenewed, the registry auto-renews it and pushes the expiry date one or two years into the future, while opening a grace window (typically 45 days) in which the registrar can hand the domain back for a credit. That is what happens when the card on file failed. The domain then reads as healthy, and the expiry ladder will not fire again for nearly two years. The registry status is the only field that distinguishes “renewed” from “auto-renewed and about to be reclaimed”.

A registry status does not change the check’s status. A domain in auto renew period still reports good, because its expiry date is in the future. The alert is the signal, so do not build a dashboard rule that looks only at the status field.

Signal 3: registrar and nameserver changes

Section titled “Signal 3: registrar and nameserver changes”

The check records the sponsoring registrar and the nameserver set on every run and alerts when either changes.

  • Registrar changed. Either a transfer you performed, or one you did not. If you did not, the domain was transferred away from you.
  • Nameservers changed. The delegation moved. This is how a hijack takes your traffic, and it usually happens before anyone notices the registrar changed.

These do not count as changes:

  • The first check on a domain, which only records the values, so enabling monitoring across a portfolio does not alert on every domain at once.
  • A registrar recasing its own name between responses.
  • A registry reordering the nameserver list. Nameservers are lowercased and sorted before comparison.

Losing every nameserver does alert. An emptied delegation is how a domain goes dark.

  • Platform-hosted hostnames get no domain check. A monitor on *.github.io, *.herokuapp.com, *.vercel.app or any of the roughly 3,200 similar shared suffixes is not paired with a domain check, because the registration belongs to the platform.
  • There is no standalone domain check. It is always paired with an HTTP check.
  • Thresholds are not configurable, and neither is the daily cadence.