# Rotate the Encryption Key

Use this procedure to rotate an existing `FLOW_ENCRYPTION_KEY` used by Flow to encrypt secrets stored in `config/config.xml` after Ingest or XL Ingest is installed and configured.

SingleStore recommends rotating `FLOW_ENCRYPTION_KEY` every 90 to 180 days, and immediately after any suspected compromise. Flow rotates the key transparently. At the first `loadConfig()` after restart, Flow decrypts each secret with the old key, re-encrypts it with the new key, and rewrites `config/config.xml`. No manual edits to `config/config.xml` are required.

Refer to [Install SingleStore Flow](https://docs.singlestore.com/db/v9.1/load-data/load-data-with-singlestore-flow/install-singlestore-flow.md) for information on initial key setup and installation.

## Prepare for Key Rotation

Before rotating the key, complete the following tasks:

* Make a copy of `config/config.xml` so the configuration can be restored if needed.
* Choose a maintenance window because Flow restarts during the rotation. Note that active extracts resume from the last checkpoint after the service starts again.
* Generate the new Base64 encoded key using the same method used for the original key.

## Rotate the Encryption Key

Perform the following steps on every Flow host, including both Ingest and XL Ingest when applicable.

1. Generate a new key using the same command used during the initial setup. Refer to [Set Up the Encryption Key](https://docs.singlestore.com/db/v9.1/load-data/load-data-with-singlestore-flow/install-singlestore-flow/#section-id235645650796082.md) for more information.

2. Set the following variables in the launcher:

   * `FLOW_ENCRYPTION_KEY` must contain the new key.
   * `OLD_FLOW_ENCRYPTION_KEY` must contain the previous key.

   **Linux launcher (`ingest.sh` or `xlingest.sh`):**
   ```shell
   export FLOW_ENCRYPTION_KEY=<NEW_BASE64_KEY>
   export OLD_FLOW_ENCRYPTION_KEY=<PREVIOUS_BASE64_KEY>
   java -cp ingest.jar:lib/*:. org.sirus.Run
   ```
   **Windows service wrapper (`ingest.xml` or `xlingest.xml`) :**
   ```xml
   <env name="FLOW_ENCRYPTION_KEY" value="<NEW_BASE64_KEY>"/>
   <env name="OLD_FLOW_ENCRYPTION_KEY" value="<PREVIOUS_BASE64_KEY>"/>
   ```
   **Windows batch launcher (`singlestore-ingest.bat` / `SingleStore-XL-Ingest.bat`):**
   ```shell
   set FLOW_ENCRYPTION_KEY=<NEW_BASE64_KEY>
   set OLD_FLOW_ENCRYPTION_KEY=<PREVIOUS_BASE64_KEY>
   java -jar ingest.jar
   ```

3. Restart the Flow service so the JVM picks up the new environment. Use `services.msc` on Windows, your service manager on Linux/macOS, or stop and restart the Java process manually for non-service deployments.

4. Confirm that the rotation completed. Check the most recent log file under `log/` for the following markers in order.
   ```shell
   Info(CMG500): Resolved AES-256 encryption key from FLOW_ENCRYPTION_KEY env var (fingerprint <NEW_FP>)
   Info(CMG503): Old encryption key configured from OLD_FLOW_ENCRYPTION_KEY env var (fingerprint <OLD_FP>); rotation enabled
   Info(CMG502): Encryption key rotation detected; re-encrypting secrets under current key
   ```
   `CMG502` is the success signal confirming that every secret in `config/config.xml` was re-encrypted with the new key and persisted. If `CMG502` does not appear after a normal startup, either no secrets were stored under the old key, or every secret was already encrypted with the new key.

5. After confirming successful rotation on ALL hosts (`CMG502` in logs), remove `OLD_FLOW_ENCRYPTION_KEY` from the configuration before the next restart. The old key is no longer needed once all secrets are re-encrypted. Keep `FLOW_ENCRYPTION_KEY` set.

## Understand Key Rotation Behavior

The following behavior is expected during key rotation.

* If `OLD_FLOW_ENCRYPTION_KEY` is set without `FLOW_ENCRYPTION_KEY`, Flow does not start. This prevents Flow from treating the previous key as the current key.
* If `OLD_FLOW_ENCRYPTION_KEY` is set to the same value as `FLOW_ENCRYPTION_KEY`, Flow logs a warning and rotation does not occur.
* If a secret cannot be decrypted with either the current key or the old key, Flow raises an error and stops. This indicates the secret was encrypted with a different key. To resolve: Stop Flow, restore `config/config.xml` from backup, set `FLOW_ENCRYPTION_KEY` to the correct original key, restart Flow, and retry rotation with the correct `OLD_FLOW_ENCRYPTION_KEY` value.
* The `CMG500` and `CMG503` log entries include a short fingerprint of the encryption key. If two processes show the same fingerprint, they are using the same key. This helps confirm which key was active without exposing the key itself.
* Rotation is applied per host. Roll out the new key to every Flow instance and confirm `CMG502` on each instance before removing `OLD_FLOW_ENCRYPTION_KEY`.

## Roll Back the Rotation

If the new key is incorrect and Flow does not start, remove `FLOW_ENCRYPTION_KEY` and, optionally, `OLD_FLOW_ENCRYPTION_KEY` from the launcher, and then restart Flow. Repeat the rotation procedure with the correct key value.

If Flow has already started with the new key and `config/config.xml` was rewritten, restore the pre-rotation backup of `config/config.xml` before retrying.

***

Modified at: July 22, 2026

Source: [/db/v9.1/load-data/load-data-with-singlestore-flow/rotate-the-encryption-key/](https://docs.singlestore.com/db/v9.1/load-data/load-data-with-singlestore-flow/rotate-the-encryption-key/)

(An index of the documentation is available at /llms.txt)
