Skip to main content
Available only for:
  • Self-hosted Bytebase 3.22.0 and later. The steps on this page need 3.24.0 or later. For 3.22.0 to 3.23.x, see Earlier versions.
  • Shell access to the host, or kubectl access to the cluster, that runs Bytebase
If nobody can sign in to Bytebase, run bytebase recovery on the server to turn password sign-in back on or to set a new password. Recovery needs no downtime. Wait one minute before you sign in. Bytebase keeps running while you recover, and it picks up the change within one minute, without a restart. If a Workspace Admin can still sign in, reset passwords, roles, and 2FA from the console instead.

Choose what to run

Recovery can’t:
  • Create or reactivate a user. The user must already exist and be active. Service accounts and workload identities don’t work.
  • Change a role that a user already has. The menu adds a role only to a user with no workspace role at all: not directly, not through a group, and not through allUsers. When such a user tries to sign in, Bytebase gives them the Workspace Member role, even if the sign-in fails, so add the role first. If no Workspace Admin is left and every user already has a role, recovery can’t restore administrator access.
  • Reset two-factor authentication. Only another Workspace Admin can reset a user’s 2FA.
  • Bypass the workspace domain. When Members restriction is on, the email must belong to an allowed workspace domain.
If none of these fits your situation, contact us.

Run recovery

No downtime, then wait one minute. Leave Bytebase running: don’t stop it before recovery, and don’t restart it afterward. After the command succeeds, wait one minute for Bytebase to pick up the change before you sign in. Run the command inside the container that runs Bytebase. That container already knows how to reach the metadata database, where Bytebase stores its users and settings, so you don’t pass any connection details: no PG_URL, no volume, and no network flags. Back up the metadata database first. A snapshot from a managed PostgreSQL service needs no downtime. The procedures in Back up and restore stop Bytebase while they copy.
The commands use the container name bytebase. Replace it with yours.
  1. Check the version:
    If it’s older than 3.24.0, follow Earlier versions instead.
  2. Run the command for your situation:
    If you start Bytebase with your own --data or --port, add the same flags at the end of the command. docker exec doesn’t pass them on.
Each command does one thing and exits:
  • enable-password-signin switches off Disallow signin with email & password. It works only when an active Workspace Admin has a password, so that someone can sign in afterward.
  • reset-password sets a new password that meets the workspace password restriction, and clears the lockout from failed attempts. It doesn’t change the user’s role, 2FA, or SSO sign-in.
When it works, the command prints one line that ends with Live within one minute., for example:
  • If reset-password also prints User <email> has no workspace role, add a role with the interactive menu before the user signs in.
  • If the command prints Error:, read the reason in Troubleshooting. When the success line appears above the error, your change was saved, and only a follow-up step failed, such as writing the audit log.
  • The command exits with status 0 only when everything succeeded. Running it again is safe: the second run changes nothing.
The password you pass with --password is saved in your shell history, and other users on the host can see it while the command runs. Change it after you sign in. To keep it hidden, use the interactive menu instead.

After recovery

  1. Wait one minute, then sign in with the email and password. Bytebase applies the change within one minute. If you sign in earlier, the new password can be rejected, and five rejected attempts within 10 minutes lock the account for 10 minutes. If that happens, run the same reset-password command again to clear the lock, then wait one minute.
  2. If you passed the password with --password, change it.
  3. Repair and test the identity provider.
  4. Switch Disallow signin with email & password back on in Settings > General > Account if it was on before.
  5. Review the recovery events in the audit log. Each action records a warning-level event whose method starts with /bytebase.cli.Recovery/.

Run recovery as a Kubernetes Job

Use a Job when you can’t run kubectl exec. The Job’s Pod runs the command once, beside the server. It must use the same image as the server and connect to the metadata database the same way. A Job only works with external PostgreSQL, which is what the chart and the manifest use.
  1. Get the exact image the server runs:
    Use the printed value as <image>, without the docker-pullable:// prefix if there is one. Don’t copy the tag from the StatefulSet: a tag such as latest can pull a newer version than the server runs.
  2. For reset-password, store the new password in a Secret, so it isn’t written in the manifest:
  3. Create the Job. This example is for a server that reads PG_URL from a Secret, which is what the chart’s existingPgURLSecret option sets up:
    • <service_account> is the service account of the server Pod.
    • Keep each argument as its own item, as shown. If you write the whole command as one item, it fails before recovery runs, and the error message shows the password.
    • Kubernetes fills in $(NEW_PASSWORD) from the Secret. If the variable isn’t defined, the command receives $(NEW_PASSWORD) as is and refuses it.
    • For enable-password-signin, use args: ["recovery", "enable-password-signin"] and remove NEW_PASSWORD.
    • backoffLimit: 0 stops Kubernetes from retrying a failed run. Never run recovery as a Deployment or StatefulSet, which would repeat it every time it exits.
  4. Read the result. The Job succeeds when the command exits with status 0:
  5. After you can sign in, delete the Job and the Secret:
Then follow After recovery.
Copy what the Job needs from the server Pod’s spec, which kubectl -n <namespace> get pod bytebase-0 -o yaml prints:With escapePassword, the init container writes the escaped password to the shared volume. Keep the init container and the volume, and give the recovery container the mount and this script:
Inside the script, write "$NEW_PASSWORD" without parentheses, so the shell doesn’t treat any character of the password as part of the script.

Use the interactive menu

Use the menu to add a role to a user, or to type the password where nobody can see it. Run bytebase recovery with no action, in the same place as the commands above, and add -it to docker exec or kubectl exec to get a terminal. Over SSH, connect with ssh -t.
The menu stays open until you enter q, so you can run several actions in a row. This example resets a password:
  • Enable password sign-in asks you to confirm with y, then does what enable-password-signin does.
  • Reset user password does what reset-password does. If the user has no workspace role, it then offers to add one: confirm, pick a role from the list, and confirm again. If you decline, the new password stays.
Each action is saved as soon as it finishes, so you can exit at any time. Then follow After recovery.

Troubleshooting

Terminal required

The interactive menu needs a terminal, so that the password stays hidden. Add -it to docker exec or kubectl exec, or run one of the two commands, which need no terminal.

Embedded metadata database may be in use

Recovery couldn’t reach the server’s embedded PostgreSQL. Usually it runs in a second container that mounts the data volume, or with a different --port than the server. Run it in the server’s container, with the server’s --data and --port. If no server is running, the lock file is left over from a crash: start Bytebase once, then run recovery in its container.

Data directory not accessible

The --data path doesn’t exist where recovery runs. Pass the same --data as the server, as an absolute path.

Embedded metadata database not initialized

This error appears only when PG_URL isn’t set. The --data directory isn’t the one the server uses. Pass the server’s --data. If the server uses external PostgreSQL, pass its PG_URL instead.

Embedded metadata database not readable

Recovery runs as a different OS user than the server. Run it as the user that owns the data directory.

External metadata database not connected

This error appears only when PG_URL is set. The text after the last colon names the cause. Recovery needs everything the server uses to reach PostgreSQL: the network, the file when PG_URL is a file path (failed to read database URL from file), TLS files, or IAM credentials. Running in the server’s container provides all of them. For a Job, compare it with the server Pod’s spec.

Unknown command

The version is older than 3.22.0. Upgrade to 3.24.0 or later, then run recovery.

Unknown subcommand

The version is 3.22.0 to 3.23.x, which has only the interactive menu. reset-password fails the same way, with Error: unknown flag: --email. Follow Earlier versions.

No usable workspace administrator

enable-password-signin needs an active Workspace Admin with a password. Run reset-password for an administrator, then try again. If no administrator is left, use the interactive menu to reset the password of a user with no workspace role and add them as Workspace Admin. If every user already has a role, recovery can’t restore administrator access.

Change not applied after one minute

Recovery saved the change to a different metadata database than the servers use. Make sure recovery uses the same PG_URL as the servers, including the database name.

Earlier versions

On 3.22.0 to 3.23.x, bytebase recovery has only the interactive menu, and the servers don’t see its change until they restart. So recovery needs downtime. Alternatively, upgrade to 3.24.0 or later first, then follow Run recovery.
Because the server is stopped, recovery runs in a new, one-off container. Unlike docker exec, that container starts with nothing, so you pass it the same image and the same metadata database settings as the server.
  1. Write down the exact version and image the server runs. Recovery must use the same version, and the restart must not upgrade Bytebase.
  2. Stop every Bytebase server that uses the metadata database, and keep them stopped until recovery exits. On Kubernetes, scale the StatefulSet to 0, and pause helm upgrade and any GitOps sync, which would restore the replicas.
  3. Back up the metadata: the data directory for embedded PostgreSQL, or the metadata database for external PostgreSQL.
  4. Run bytebase recovery in a one-off container, with a terminal. For embedded PostgreSQL with Docker, mount the same data volume as the server:
    For external PostgreSQL with Docker, pass -e 'PG_URL=<pg_url>' instead of the volume. On Kubernetes, pass the same PG_URL, and press Enter if the menu doesn’t appear:
    Also pass anything else the server uses to reach PostgreSQL: the network, a mounted connection-string file or TLS certificate, and IAM credentials. On Kubernetes, when PG_URL comes from a Secret, a file, or IAM authentication, create a Pod with the same env, volumes, volumeMounts, and serviceAccountName as the StatefulSet’s Pod template, then kubectl exec -it into it. With a binary on a host, run the same binary as the same OS user, with the same --data or PG_URL.
  5. Use the menu as described in Use the interactive menu. On these versions, nothing takes effect until you restart Bytebase.
  6. Start Bytebase again on the image you wrote down, without a floating tag such as latest and without --pull always. On Kubernetes, pin the tag first, then restore the replica count.