Skip to content
NebulaCtrldocs

Control plane

Fix control plane start failures, sign-in and permission refusals, refused event streams, internal errors and failed console updates, by the message you see.

Use this page when nebula serve does not start, a request is refused with a permission message, or a console update does not finish. Each entry starts with the message you see.

usage: --<setting> (NEBULA_<SETTING>) must be set

Cause: nebula serve exits with code 2 and this message when a required setting is empty. The message lists every missing setting at once, each as its flag and environment variable separated by commas, for example usage: --database-url (NEBULA_DATABASE_URL), --master-key (NEBULA_MASTER_KEY) must be set. In a terminal it starts with nebula: . The required settings are database-url, master-key, base-url, oidc-issuer, oidc-client-id and oidc-client-secret. Each reads from a flag, a NEBULA_ environment variable, or nebula.yaml in the working directory or /etc/nebula.

Fix: Set each named setting. See the configuration reference.

Verify: The process logs database connected and keeps running.

master key must decode to 32 bytes, got <count>

Cause: The control plane prints this at start, after decode current master key:, when master-key is not base64 of exactly 32 bytes. A key that is not base64 reads master key is not valid base64.

Fix: Set the original key value from your backup of the installer's environment file. Do not generate a new key for an installation that already stores secrets; every stored secret would become unreadable. To rotate, list the old key in previous-master-keys and run nebula secrets reseal. See backup and restore.

Verify: The process starts past the key check and logs database connected.

reach database at <url>: <error>

Cause: The control plane opens its database pool at start and refuses to run when the database does not answer. A malformed URL reads parse database url: <error>.

Fix: Correct database-url, start PostgreSQL, and open the network path to it.

Verify: The log shows database connected with the host and database name.

timescaledb is not installed on this Postgres server, so the telemetry tables cannot be migrated and nothing was changed

Cause: The migration at start requires the TimescaleDB extension. The message continues with the fix. An older extension reads timescaledb <version> is older than 2.13, which nebula needs for by_range hypertables.

Fix: Install TimescaleDB 2.13 or newer, add timescaledb to shared_preload_libraries, restart PostgreSQL, then start the control plane. For an old extension, run ALTER EXTENSION timescaledb UPDATE. See requirements.

Verify: nebula migrate status lists every migration as applied.

discover OIDC issuer "<issuer>": check the issuer URL, TLS certificate and discovery document: <error>

Cause: The control plane contacts the identity provider at start and refuses to run without its discovery document. Two earlier checks read OIDC issuer "<issuer>" is not a valid URL; check oidc-issuer and OIDC issuer "<issuer>" is not https; use https or enable oidc-insecure-http for development only.

Fix: Correct oidc-issuer so it is the provider's HTTPS address, and make its certificate trusted by the host. See sign-in.

Verify: The control plane starts, and the console redirects to your provider.

this organization requires two-factor sign-in and you signed in without it; sign out, then sign in again using a second factor at your identity provider

Cause: The API answers 403 with this detail when the organization requires a second factor and your session has none. Only the session endpoints stay reachable.

Fix: Sign out, then sign in again and complete the second factor at your identity provider.

Verify: The organization loads without the refusal.

Too many sign-in attempts. Wait a minute, then try again.

Cause: The sign-in start and callback routes answer 429 with this text after a burst of 20 attempts from one address, then allow one attempt every 3 seconds.

Fix: Wait one minute, then sign in once. Behind a reverse proxy, set trusted-proxies so the limit counts each person's address, not the proxy's.

Verify: The sign-in redirect proceeds to your provider.

sign in or provide an API token to <action>

Cause: The API answers 403 when the request carries no valid credential. A revoked, expired or mistyped token counts as none, as does a session cookie sent on a write without the X-Nebula-CSRF: 1 header.

Fix: Send Authorization: Bearer nbl_<id>_<secret> with a token from API tokens, or sign in again in the console.

Verify: The request returns 2xx instead of 403.

X-Nebula-Organization must be an organization id

Cause: The API answers 400 when the header holds anything but an organization UUID. A session request with no header gets X-Nebula-Organization header is required to <action>.

Fix: Send the organization's UUID. An API token already belongs to one organization, so it can omit the header.

Verify: The request no longer answers 400.

you are not a member of that organization

Cause: The API answers 403 when the session's user does not belong to the organization in X-Nebula-Organization.

Fix: Send the id of an organization you belong to, or ask an owner for an invitation. See members and teams.

Verify: The request succeeds with your role applied.

this API token belongs to another organization

Cause: The API answers 403 when X-Nebula-Organization names an organization other than the token's own. A token is fixed to one organization.

Fix: Remove the header, or create a token in the other organization.

Verify: The request succeeds.

this API token has the <role> role, which cannot perform <action>; create a token with a role that carries it

Cause: The API answers 403 because the token's role (viewer, deployer or admin) does not carry the action.

Fix: Create a token with a role that carries the action and send it instead.

Verify: The request returns 2xx.

your role in this organization is <role>, which cannot perform <action>; ask an admin or the owner

Cause: The API answers 403 because your role does not carry the action.

Fix: Ask an admin or the owner to run the action, or to change your role.

Verify: The action succeeds, or the owner's change shows under your name in the member list.

refused: this credential already holds the maximum number of open streams

Cause: Log, build log and deployment streams arrive as a single comment frame with this text when one credential already holds 4 open streams. A stream ends by itself after 15 minutes.

Fix: Close console tabs or curl -N sessions that hold a stream, then reconnect.

Verify: The stream delivers log events instead of the comment.

refused: this caller already holds the maximum number of open event streams; close one and reconnect

Cause: The organization event stream, /api/v1/events/stream, allows 8 open streams per user or token, and each lasts 30 minutes.

Fix: Close the extra consumers, then reconnect.

Verify: The stream sends change events.

Something in the control plane failed while handling this request

Cause: The API answers 500 with Nothing was changed. Quote request id <id> when reporting it. A panic in a handler answers with the same sentence without Nothing was changed.

Fix: Search the control plane log for the id in the request_id field. The line unhandled request failure or request handler panicked holds the error. Include the id and that line when you report it.

Verify: The log line exists for the id you quote.

the API description could not be rendered

Cause: GET /api/openapi.json answers 500 with this plain text when the control plane cannot build its OpenAPI document. See the API.

Fix: Read the render openapi document line in the control plane log and include its error when you report it.

Verify: GET /api/openapi.json returns JSON.

Update to <version> failed and was rolled back

Cause: The console shows this on the Updates page when the new release did not come up. The updater reinstalled the previous release, and the message ends with Read the installer output below, fix the cause, then request the update again. If the reinstall also fails, the title reads Update to <version> failed.

Fix: Select Show installer log, remove the cause, then select the Update to button for that version again. For a failed reinstall, run the curl command in the message on the host.

Verify: The page reads Updated to <version>.

No updater has reported to this control plane yet

Cause: The Updates page offers no update button, and the API answers 409, until the nebula-updater service polls. Related texts: The updater has been offline since <time> after 2 minutes of silence, and This control plane has no updater token.

Fix: Run sudo systemctl status nebula-updater on the host. If the service is missing, run the installer again. Only owners of the Default organization can request an update.

Verify: The page shows Update to the newest version.

NebulaCtrl was updated to <version>.

Cause: A console tab left open across an update shows this banner, because the page still runs the old code against the new API.

Fix: Select Reload. Anything you typed and did not save is lost.

Verify: The banner disappears.

On this page