Retry-After header.
The page shows:
- the error code, a title and a message
- the chain You → Proxy → Destination, with how each hop is doing (for maintenance: your browser connected, the proxy connected, the site maintenance)
- Try again and More information buttons
- a request ID and the time, and “Powered by DNZ”
Which names can have one
Plain DNS can’t show a page: it only hands out addresses. So only names a proxy serves can have a status:- the name of a proxied record (see Proxied records), or
- a router’s host on one of the proxies (see Routing).
*.example.com covers one label below
example.com (app.example.com, not a.b.example.com). When a host has a status of its own and a
wildcard covers it too, its own status wins. A host has at most one status.
Statuses
Each status can get its own title and message instead of the usual ones (up to 120 and 2000
characters; a message keeps its line breaks), and a link for the More information button, for
example your status page or an announcement.
Setting one
- Dashboard
- CLI
- API
1
Open Status pages
Go to DNS → Status pages and click New status page. Or, in a zone, open a proxied
record and pick Status page…: the same dialog opens with the record’s name filled in.
2
Pick the host and the status
The host field offers the names a proxy serves, with the proxies serving each.
3
Fine-tune it
Optionally give a title, a message, a schedule, allowed addresses and a link. For Moved,
give the new address and whether to keep the path. The preview shows the page as visitors
will see it.
4
Save
Every dnz-proxy node serving the host shows the page within seconds.
Schedule and Retry-After
A status is on from the moment it is saved until it is turned off, unless it has a window:- Starts at: it waits until then (scheduled), and visitors reach the backend as usual.
- Ends at: it stops on its own (ended). Until then, the page shows Expected back with that
time, and
Retry-Aftercounts down the seconds to it.
Retry-After is only sent for rate_limited (60 seconds).
Schedules are evaluated by the proxy nodes themselves, so a status starts and ends on time even
while a node can’t reach DNZ. A change made in DNZ reaches every dnz-proxy node within seconds.
Letting some visitors through
Allowed addresses (IPs and CIDRs, up to 100) reach the backend as usual, for example your office network, or the team checking the site after maintenance:Moved
moved needs the new address (https://new.example.com). Visitors get a 301 with
Location: <new address>. With keep path, the path and query come along:
https://old.example.com/docs?page=2 goes to https://new.example.com/docs?page=2.
How each proxy shows it
dnz-proxy
dnz-proxy
The statuses come with the configuration DNZ pushes to the nodes, within seconds of a change.
Each node renders the page itself and starts and ends scheduled statuses on its own clock. The
page is checked after the router matches and before its middlewares, so Let’s Encrypt’s HTTP-01
checks still get through.
Caddy
Caddy
Each status becomes a route in front of the site’s routes that answers with the page itself
(
static_response, one each for HTML, JSON and text). Allowed addresses are left out with a
not remote_ip matcher. The request ID and time come from Caddy ({http.request.uuid},
{time.now.http}), and Moved with keep path sends visitors to
<new address>{http.request.uri}. Caddy fetches its configuration every 10 seconds, so a status
(or the start or end of its window) shows up within that.Traefik
Traefik
Each status becomes a router with a higher priority than any of DNZ’s for the host, on the same
entry points and with the same TLS. It sends visitors to DNZ’s
/api/proxy/status-page, at the
address the Traefik reached DNZ on, unless their address is allowed (!ClientIP(...)). DNZ
renders the page there. Traefik polls every 5 seconds by default, and it has to reach DNZ’s HTTP
port, which it already does to poll.Automatic pages for the proxy’s own failures
dnz-proxy also shows a styled page when it can’t get an answer from the backend, for every host and with no setup:
These can’t be set by hand.
HTML, JSON or text
The page comes in the form the visitor asks for withAccept:
-
Browsers (
text/html) get the HTML page. -
API clients (
Accept: application/json) get JSON.until,locationandlinkare only there when they are set: - Everything else gets plain text.
Cache-Control: no-store, X-Robots-Tag: noindex and X-Request-Id, so a cache
never keeps the page after the status is lifted. Proxy → Analytics counts these visits under
Firewall rules as status maintenance (and so on), and the request log shows them.
Who can set one
- Superadmins manage every status.
- Others manage statuses of hosts in zones where they have
records.write, and see those of zones they can view (zones.read). - A host in none of DNZ’s zones (a router’s host for a domain DNZ doesn’t hold) is superadmin-only.
status_page.create, .update, .enable, .disable or
.delete.
Next steps
Status pages in the CLI
Set, schedule and lift statuses from the terminal.
Status pages API
The endpoints and the fields of a status.