Edgeweir
Guides

Error pages

The error pages nodes answer with: a site's templates and redirects, maintenance mode, platform templates, built-in pages, and the request ID of every request.

Concepts

TermDefinition
Site error pageAn HTML template or redirect URL a site sets for a status or for Other 4xx / Other 5xx, replacing the node's built-in page and, optionally, the origin's error responses.
Maintenance modeThe site is paused: every request but those from allowed addresses and paths gets the 503 maintenance page.
Platform error pageAn HTML template for unknown hosts and disabled sites.
Built-in pageThe page nodes use without a template, in Chinese or English by Accept-Language.
Request IDThe ID a node settles for each request; it appears in the X-Request-Id response header, in error pages and in sampled logs.
Offline hostA domain of a disabled site; nodes answer it with the platform's disabled page instead of the unknown host page.

Set a site's error pages

  1. Open Sites, select the site, and go to the Error pages tab.

  2. Enter an HTML template in the field of a status; statuses left empty use the built-in page. To redirect instead, choose Redirect to URL above the status and enter the URL; a template page can change the status it is sent with in Response status.

  3. To replace errors the origin returns itself, turn on Replace origin error responses.

  4. Click Save. The console publishes a revision ("Error pages of {site} updated"); nodes hot-update without a reload.

  5. Verify:

    curl -s -D - -H 'Host: www.example.com' http://<node IP>/<a path a rule denies>

    The answer is 403 with Content-Type: text/html; charset=utf-8, Cache-Control: no-store and the template.

StatusResponses that use the pageX-Edgeweir-Error
403 ForbiddenRule and IP list denials (including rate limit rules set to 403), bans and automatic CC bans, OWASP CRS blocks, WebSocket upgrades while WebSocket is offpolicy-denied, ip-banned, waf-blocked, websocket-disabled
429 Too Many RequestsRate limit rulespolicy-denied
502 Bad GatewayThe node cannot connect to the origin, every origin was dropped before the attempt, origin signing failedorigin-unreachable, no-origin, and others
503 Service UnavailableThe node cannot complete a check for now (for example, challenge keys not delivered yet)challenge-unavailable, policy-unavailable
504 Gateway TimeoutThe origin timed outorigin-timeout
400 Bad requestRequests the node cannot parse, request headers too large, plain HTTP on an HTTPS port (when the site is known)bad-request, header-too-large, https-required, waf-blocked
405 Method not allowedMethods an S3 origin does not takemethod-not-allowed
500 Server errorThe node failed while handling the request (when the site is known)internal-error
401 Unauthorized, 404 Not found, 410 GoneOnly to replace errors the origin returnsorigin-error
Other 4xx / Other 5xxThe 4xx / 5xx without a page of their own above: the node's 413 and 414 and other statuses from the originAs for the status
Lookup orderDescription
1The status's own page
2Other 4xx or Other 5xx
3The built-in page; an origin error without a page passes through
ItemBehavior
Replace origin error responsesWhen on and the origin itself returns 400–599 and the lookup finds a page, the node returns that page instead (origin-error); without a page the origin's response passes through
Stale content firstWhen a rule sets Stale if error (s) and the node holds an expired copy, the stale copy wins over the error page; once the expired copy may no longer be served, the answer is the 502 page (origin-unreachable)
Not cachedError pages carry Cache-Control: no-store, and nodes never store them in the cache
Other statusesThe node's own 404 (ACME challenge not found), 421, 508 and others stay plain text; a non-GET/HEAD request without a pass refused by a challenge (X-Edgeweir-Challenge: required) is plain text too
AuditChanges are audited as site.error_pages_update (the statuses that changed and their sizes, not the templates)

Redirect pages

With Redirect to URL, responses of that status become a 302 redirect.

ItemRule
URLAn absolute http:// / https:// URL (lower-case scheme, a domain or a bracketed IPv6 address as host, no user information, an optional port) or a path starting with a single /; 1–2048 printable ASCII characters without spaces or \; every % followed by two hex digits
PlaceholdersOnly {{status}} and {{request_id}}, not in the host or port, URL-encoded when inserted, e.g. /error?code={{status}}&id={{request_id}}
Response302, Location, Cache-Control: no-store, X-Edgeweir-Error, an empty body
Response statusRedirect pages are always 302; an HTML template page can set 200–599 to change the status it is sent with, empty keeps the status

Maintenance mode

In the Maintenance mode card on the Error pages tab, turn on Enabled, fill in Retry-After (seconds), Allowed addresses, Allowed path prefixes and Maintenance page as needed, and click Save. The other settings are kept while it is off.

FieldValuesDefaultEffect
EnabledOn / offOffTurns maintenance mode on
Retry-After (seconds)0–864000 (not sent)Retry-After of the 503 response
Allowed addressesIPs or CIDRs, up to 64; IPv4-mapped ::ffff: addresses are saved as the IPv4 they map, mapped prefixes under /96 are refused (as in IP lists)EmptyRequests from these addresses are served as usual
Allowed path prefixesStart with /, no query or fragment, at most 1024 bytes of UTF-8 each, up to 32EmptyRequests whose path starts with one of them are served as usual
Maintenance pageHTML template, rules as for templatesEmpty (built-in maintenance page)The page of the 503 response
ItemBehavior
Response503, X-Edgeweir-Error: maintenance, Cache-Control: no-store; no cache lookup and no origin request, and nothing answered during maintenance enters the cache
WhereAfter bans and PURGE, before the rules; allowed addresses are matched against the visitor address (the rules' ip.src, set by the cluster's client IP), allowed prefixes against the normalized path before rule rewrites
ACMEHTTP-01 validation requests for certificates are not affected
ApplyingSaving publishes a revision ("Maintenance of {site} updated"); nodes hot-update
Auditsite.maintenance_update
Node requirementsite-content-v1; while an active node of the cluster lacks it, maintenance cannot be turned on, but it can be turned off

Templates

ItemRule
Size1–65536 bytes (UTF-8) per template
ContentSent as is; nodes neither check nor escape the template itself, and the site answers for the scripts, styles and images it references
PlaceholdersThe six below; values are HTML-escaped (&, <, >, ", ') before they are inserted; any other {{…}} stays as it is
Response headersContent-Type: text/html; charset=utf-8, Cache-Control: no-store, X-Edgeweir-Error, X-Request-Id
PlaceholderValue
{{status}}The status, e.g. 403
{{request_id}}The request ID, the same as the X-Request-Id response header
{{client_ip}}The visitor's IP, the same as ip.src in rules (under the cluster's client IP setting)
{{host}}The request's Host, lowercase, without the port; empty when the request has no valid Host
{{time}}When the node answered, UTC, RFC 3339, e.g. 2026-10-06T12:34:56Z; needs rules-v3
{{path}}The request path ($uri after nginx normalization, the same as http.request.uri.path in rules: the rewritten path after a rewrite); needs rules-v3

Example:

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>{{status}}</title>
<h1>We could not complete your request</h1>
<p>Request ID: {{request_id}}</p>
<p>{{time}} · {{path}}</p>

Built-in pages

Without a template, nodes answer with a self-contained built-in page: no external resources, no script, light or dark with the system. The page shows the status and the path from the visitor through the edge node to the origin, marking the hop that failed (the visitor, the edge node or the origin) and its state; below come the title, what the visitor can do, Reload where reloading can help, and the request ID, the time the node answered (UTC), the host and the visitor's IP (shown on click). Motion is CSS only and stops when the system asks for reduced motion. The language is Chinese or English, whichever ranks highest in Accept-Language; English when neither is listed.

PageStatusX-Edgeweir-Error
Access denied / Too many requests / Origin unreachable / Service unavailable / Origin timed out403 / 429 / 502 / 503 / 504See above
Method not allowed405method-not-allowed
Under maintenance503maintenance
Site not found404unknown-host
Site disabled503site-disabled

Requests the node refuses and the node's internal errors use the site's pages in the lookup order when the site is known, else the built-in page. A refused request marks the visitor on the path, an internal error the edge node:

PageStatusRequestsX-Edgeweir-Error
Bad request400Requests that do not parse (for example a TLS handshake on an HTTP port), a missing or invalid Host; a request body the OWASP CRS cannot parsebad-request; waf-blocked when the CRS refuses it
Request header too large400A request header over 8 KB or all headers over 32 KB, usually too many cookiesheader-too-large
HTTPS required400Plain HTTP sent to an HTTPS porthttps-required
URL too long414A request line over 8 KBuri-too-long
Request too large413A request body over the site's or a rule's request body limit, or a chunked request over the node-wide limitbody-too-large
Edge error500The node failed while handling the requestinternal-error

Platform error pages

Set them under System settings → Platform error pages, with the rules of site templates; empty fields use the built-in page. Saving publishes a revision for every cluster ("Platform error pages updated") and is audited as system.error_pages_update, see System settings.

FieldRequests it applies toStatus
Unknown hostThe Host belongs to no site of the cluster and is no offline host404
Site disabledThe Host is a domain of a disabled site503

Nodes recognize disabled sites from the offline host list in their configuration (the domains of disabled sites); wildcards match as site domains do. Once the site is enabled again, the host is served again; once the site is deleted or the domain removed from it, the host is no offline host any more and answers 404. Both pages are for HTTP requests only: nodes complete no TLS handshake for these hosts, so HTTPS requests fail in the handshake.

Request IDs

ItemBehavior
SettledAn X-Request-Id request header matching ^[A-Za-z0-9._:-]{8,128}$ is kept; otherwise the node generates a 32-character hexadecimal ID
ResponseEvery response carries X-Request-Id; an X-Request-Id the origin returns is replaced
OriginForwarded to the origin as the X-Request-Id request header
LogsSampled access logs record it; the Logs tab looks it up exactly by Request ID, and the CSV has a requestId column, see Access logs

Node requirements

FeatureRequirement
Site error pagesNode feature error-pages-v1; while an active node of the cluster lacks it, pages cannot be saved ("Some nodes of the site's cluster do not support it yet")
Platform error pages, offline hostsNo feature needed; older nodes ignore them, keep their plain-text answers and answer offline hosts with 404
{{time}}, {{path}}A site template or platform page that uses them makes the configuration need the node feature rules-v3; while an active node of the site's cluster lacks it, the Error pages tab leaves the two placeholders out and shows "Some nodes of the site's cluster do not support it yet" when a template uses them; a platform page that uses them shows "{{time}} and {{path}} need nodes with rules-v3; older nodes keep their last configuration". Nodes without the feature keep their last-known-good configuration, see Node capabilities and publishing
Built-in pages for refused requests and internal errorsNo feature needed; older nodes answer with nginx's own error pages
400, 401, 404, 405, 410, 500, Other 4xx, Other 5xx, redirect pages, response status, maintenance modeNode feature site-content-v1; while an active node of the cluster lacks it, the Error pages tab lists only the original five statuses, offers no redirect or response status, and shows "Some nodes of the site's cluster do not support it yet"
Template spaceTemplates travel with the site table into the node's shared memory; with many sites and large templates raise the node flag --sites-dict-mb (default 64)

Troubleshooting

SymptomCauseAction
Still a plain-text errorThe node is too old; the node's own status has no page (404, 421, 508)Upgrade the node, see Node upgrades
An error page ending in "openresty"The node is too old: that is nginx's own pageUpgrade the node
The origin's error page is not replacedReplace origin error responses is off, or neither the status nor its class has a pageTurn it on and set a page for the status or for Other 4xx / Other 5xx
The redirect URL shows "Check “Redirect to URL”"The URL is no http(s) URL or path starting with /, has spaces or other placeholders, or exceeds 2048 charactersFix the URL; use only {{status}} and {{request_id}}
Every visitor sees the maintenance pageMaintenance mode is on and the visitor's address and path are not allowedTurn maintenance off, or add allowed addresses or path prefixes
An allowed address still gets the maintenance pageWith a proxy in front of the node and the cluster's client IP set to direct, the visitor address is the proxy'sSet the cluster's client IP to PROXY protocol or a trusted proxy header, or allow the proxy's range
Saving shows "The … error page is larger than 65536 bytes"The template exceeds 64 KiB in UTF-8Shorten the template; host large images elsewhere
A disabled site answers 404The node is too old to know offline hostsUpgrade the node
The request ID of a page is not in the logsAccess logs are off or the request was not sampledRaise the sample rate on the Logs tab
Edit on GitHub

On this page