---
id: platform/maintenance-mode
title: Maintenance mode
description: Redirect public requests to a maintenance response on a paid Bex web service, verify the change, and restore normal routing.
keywords: [bex, maintenance mode, public traffic, service operations]
last_updated: 2026-09-23
---

Maintenance mode directs a web service's public ingress to a maintenance
responder. Use it when you need to stop normal public requests while preparing
or checking an application change.

It does **not** itself suspend the service, stop background writers, or block
private connections. The service's independent suspension and scaling settings
still apply. For a database cutover, stop every relevant writer separately;
see the [migration procedure](./migrate-from-render.md).

## Prerequisites

Bex supports maintenance mode for paid web services. Free web services and
other service types are rejected. You need operate access to the service and
an [API bearer token](./api.md) for API calls.

The installation must have working public ingress and the shared maintenance
responder. Saving the setting requests a routing change; verify the response
from each public hostname before relying on it.

## Enable the default response

Set `SERVICE_ID` to the ID returned by Bex. This PATCH updates the
`serviceDetails.maintenanceMode` object:

```bash
curl --fail-with-body --silent --show-error \
  -X PATCH "$BEX_API_URL/v1/services/$SERVICE_ID" \
  -H "Authorization: Bearer $BEX_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"serviceDetails":{"maintenanceMode":{"enabled":true,"uri":""}}}'
```

Supply both `enabled` and `uri` whenever you supply that object. An empty `uri`
selects the built-in maintenance page. Omitting the whole object leaves the
setting unchanged.

For a [Blueprint-managed service](./blueprints.md), declare the setting in its
service entry so the next sync preserves your intent:

```yaml
maintenanceMode:
  enabled: true
  uri: ""
```

This is a fragment of an existing paid web service entry, not a complete
manifest. Validate the complete manifest before applying it.

## Verify public and private behavior

Set `PUBLIC_URL` to a returned service URL or a configured custom-domain URL:

```bash
curl --silent --show-error --include "$PUBLIC_URL"
```

The built-in response uses `503 Service Unavailable` and `Cache-Control:
no-store`. Check the platform hostname and each [custom domain](./custom-domains.md)
you use. A stored `enabled: true` alone does not prove ingress has reconciled.

Where private access is configured, verify it separately from an authorized
workload. Maintenance mode changes public routing, not
[private-network](./private-network.md) policy. Existing work or long-lived
connections should not be treated as canceled by a routing change.

If public traffic still reaches the application, have the installation operator
check ingress reconciliation and the maintenance responder before proceeding.
Do not substitute [suspension](./app-lifecycle.md) without considering its
separate effects on the workload.

## Use a custom page

Set `uri` to an absolute HTTP or HTTPS URL served independently of this Bex
installation. Bex rejects URLs pointing to the same service, reserved platform
hosts, or another service's claimed hostname on the platform, to prevent fetch
loops. A static site on the same Bex installation is therefore not a suitable
custom-page host.

The responder fetches that page. A successful upstream response is served with
maintenance status `503`; upstream error statuses are preserved. A fetch or
response-size failure returns `502`, rather than silently selecting the default
page. Test the actual public response, including body and status, before the
maintenance window.

## Restore normal traffic

Send the same PATCH with `{"enabled":false,"uri":""}` inside
`serviceDetails.maintenanceMode`. This disables maintenance and clears the
custom URL. To retain a custom URL for later, send that URL with `enabled: false`.
Update the Blueprint declaration too if it manages the setting.

Read the service back and verify normal responses on every public hostname.
If traffic still fails, check readiness, suspension, scaling, and DNS; disabling
maintenance does not repair an unhealthy application. Ordinary redeployment
does not itself clear the maintenance setting.

Use [audit logs](./audit-logs.md) to inspect maintenance changes and
[application logs](./logging.md) to check application behavior after reopening.
