Maintenance mode
This page is for administrators who need to take a site offline for a while: an upgrade, a data import, a reinstall. Maintenance mode takes the whole public site offline, shows visitors a friendly page, and brings it back with one command or one button. The Kickstarter and the web setup wizard use the same mechanism, so a site that is being installed never serves a half-built page.
For a step-by-step guide with screenshots, workflows and troubleshooting, read the user guide Maintenance mode: taking the site offline and bringing it back.
Quick start:
php bin/php/maintenance.php on --message="Back at 06:00" --until=2h --allow-root-user
curl -sI https://www.example.com/ | head -1 # HTTP/1.1 503 Service Unavailable
php bin/php/maintenance.php off --allow-root-userWhat a visitor sees
While maintenance is on, every request to index.php, index_rest.php and
index_treemenu.php is answered with the maintenance page before the settings
or the database are touched:
- HTTP status
503 Service Unavailablewith aRetry-Afterheader Cache-Control: no-storeandnoindex, so no cache or search engine keeps it- images, styles and scripts are still served, so the page keeps its look
The page is the active theme's errors/maintenance.html when an active
extension has one, otherwise share/maintenance.html. It is a self-contained
HTML file with {placeholders}. A default installation now has a
favicon.ico at the document root and the default page links it.
Switch it on and off
From the command line
php bin/php/maintenance.php on --message="Back at 06:00" --until=2h
php bin/php/maintenance.php status
php bin/php/maintenance.php off
./console exp:maintenance on|off|status # the same, through the consoleRun as root, add --allow-root-user to php bin/php/maintenance.php (the
script refuses otherwise). php bin/php/maintenance.php --help lists the options.
| Option | Meaning |
|---|---|
--message="..." | What the page says, instead of the default text. |
--until=30m / 2h / "2026-09-28 06:00" | Expected end, shown to visitors and sent as Retry-After. |
--allow-ip=1.2.3.4,5.6.7.8 | Addresses that still see the site. |
--allow-admin | Keep the administration (/admin) reachable. |
Switching on also empties the caches that answer ahead of index.php.
From the administration
Setup > Maintenance (/setup/maintenance) does the same. Since 5 October
2026 it is laid out task first, in the look of the cronjobs page:
- A state banner at the top: green when the site is online; amber in maintenance, with the reason (window, installation, setup wizard, unreadable marker), who switched it on, since when and for how long, the expected end and the time left, a warning once that end has passed (maintenance never ends by itself), and whether you yourself see the site or the maintenance page. The one action the state calls for sits in the banner: Bring the site back online, with a warning when an installation still holds maintenance.
- Online, a three-step plan: the message (with a character counter), the
expected duration (one click for 15 min, 30 min, 1 h, 2 h or 4 h, and the
local and UTC time it means), and who still gets in (the administration under
/adminalways; your own address with one tick; other addresses, checked as you type and again on the server, which names what it left out). A required confirmation guards Take the site offline. - A preview of the page visitors get: the real maintenance page, filled in, in a sandboxed frame; it follows the message and duration as you type. Offline, it shows the page being served, with the message and the list of who still gets in.
- From a shell: the
on,offandstatuscommands with Copy buttons. - Recent changes: the latest eight
system.maintenance.changeevents from the audit index, linked to the audit console (needsaudit / readon thesystemchannel).
It needs the setup / administrate right and the form carries the
administration's form token; field and button names are those of the earlier
page. It works without JavaScript (the confirmation is a required checkbox, the
sections are <details>), holds from 390 pixels up and at 200 % zoom, and keeps
a 4.5:1 text contrast in admin4's light and dark modes; the same template serves
the older admin design. The administration stays reachable while the site is
offline, otherwise the page that switches it off could not be opened. The
address you switched it on from is let through only when Let my own address
still see the site is ticked (before 27 September it was always let through,
so to the administrator it looked as if nothing had happened).
The full user guide, with screenshots, workflows, a safety checklist and troubleshooting: Maintenance mode.
How it works
State is one file, var/maintenance.json. While it exists, the front
controllers include kernel/classes/expmaintenance.php first (plain PHP, no
autoloader, no database) and answer with the page. A marker that cannot be read
still means maintenance: a maintenance page is better than a half-changed site.
| Marker field | Meaning |
|---|---|
reason | unknown, an installation, setup (web wizard) or a manual window. |
message, until | Shown on the page. until is a Unix time; Retry-After is the seconds left, or 120 when no end is set. |
allow_ips, allow_paths | Addresses and paths still served (--allow-admin adds /admin). |
lease | Web wizard only: the marker expires 900 seconds after the wizard's last posted step. |
allow_token | Web wizard only: SHA-256 hash of the cookie that lets the wizard's own browser through. |
Installations use it automatically
- Kickstarter: switches maintenance on when a run begins and off when the
site is installed and checked. After a failed step it stays on and says how
to end it (
php bin/php/maintenance.php off). - Web setup wizard: its first posted step (never a GET, never a page being
shown) switches maintenance on with reason
setupand gives its browser a random cookie (exp_setup_wizard); every other visitor gets the maintenance page instead of a second wizard that would abandon or overwrite the first run. Each posted step renews the 15-minute lease (expMaintenance::WIZARD_LEASE= 900 seconds) and the cookie with it, so a wizard that is left gives the site back within 15 minutes by itself. The last page switches maintenance off and clears the cookie. On an installed site the wizard does not run at all: see the setup wizard.
Before this, requests that arrived during an installation met half-built tables
and logged errors that were not the installation's ("no such table:
ezurlalias_ml"). A reinstall verified with one request per second showed 93
maintenance answers during the run and an error.log that held only the run's
own begin and end entries.
Velocity and other caches
The generated Velocity site configuration names the marker as its cache pause file, so under Velocity the response caches pause during maintenance too (engine release 0.0.4.34 and later).
Related pages
- Maintenance mode: the user guide
- Installing with one command, Kickstarter, setup wizard
- Velocity: running Exponential in a persistent-worker web server
- Installer logs and seed data
- Chronicle, 16 to 30 September 2026
- Behaviour changes, 16 to 30 September 2026
- Changelog 6.0.15
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.