SonarSource/sonarqube · critical · IllegalStateException

"No secret key in the file: " + path

Error message

"No secret key in the file: " + path

What it means

AesCipher.loadSecretFileFromFile throws this IllegalStateException when the secret key file exists and is readable but its content is empty or whitespace-only. AesCipher expects the file to contain a non-blank Base64-encoded AES key, so an empty file means the encryption setup was never completed properly.

Source

Thrown at sonar-plugin-api-impl/src/main/java/org/sonar/api/config/internal/AesCipher.java:78

    return false;
  }

  protected Key loadSecretFile() throws IOException {
    String path = getPathToSecretKey();
    return loadSecretFileFromFile(path);
  }

  Key loadSecretFileFromFile(@Nullable String path) throws IOException {
    if (StringUtils.isBlank(path)) {
      throw new IllegalStateException("Secret key not found. Please set the property " + ENCRYPTION_SECRET_KEY_PATH);
    }
    File file = new File(path);
    if (!file.exists() || !file.isFile()) {
      throw new IllegalStateException("The property " + ENCRYPTION_SECRET_KEY_PATH + " does not link to a valid file: " + path);
    }
    String s = FileUtils.readFileToString(file, UTF_8);
    if (StringUtils.isBlank(s)) {
      throw new IllegalStateException("No secret key in the file: " + path);
    }
    return new SecretKeySpec(Base64.decodeBase64(StringUtils.trim(s)), CRYPTO_KEY);
  }

  String generateRandomSecretKey() {
    try {
      KeyGenerator keyGen = KeyGenerator.getInstance(CRYPTO_KEY);
      keyGen.init(KEY_SIZE_IN_BITS, new SecureRandom());
      SecretKey secretKey = keyGen.generateKey();
      return Base64.encodeBase64String(secretKey.getEncoded());

    } catch (Exception e) {
      throw new IllegalStateException("Fail to generate secret key", e);
    }
  }

  String getPathToSecretKey() {
    if (StringUtils.isBlank(pathToSecretKey)) {

View on GitHub (pinned to 184c821202)

Solutions

  1. Regenerate the secret key (Base64, 16 bytes for AES) and write it to the configured file, then restart SonarQube.
  2. Verify the file is non-empty: cat the path from the exception and check it contains a Base64 key.
  3. Ensure the key generation completed successfully (check logs of the encryption/secret-key step).
  4. If using a mounted volume, confirm the mount actually contains the key, not an empty placeholder.

Example fix

# before: empty file -> IllegalStateException
$ touch /opt/sonarqube/conf/secret.key
# after: write a valid Base64 secret key
$ openssl rand -base64 16 > /opt/sonarqube/conf/secret.key
Defensive patterns

Strategy: validation

Validate before calling

String content = FileUtils.readFileToString(new File(secretKeyPath), StandardCharsets.UTF_8);
if (content.isBlank()) {
  throw new IllegalStateException("Secret key file is empty: " + secretKeyPath);
}

Try / catch

try {
  Key key = aesCipher.loadSecretFile();
} catch (IllegalStateException e) {
  LOG.error("Regenerate the secret key file: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling loadSecretFile() with sonar.secretKeyPath pointing to a file that was created but never populated — e.g. an empty file created by touch, a failed/aborted key-generation step, or a file truncated by a bad write/mount.

Common situations: Operator created an empty placeholder file to silence a previous 'file not found' error; key generation script failed midway; Docker volume mount left the file empty; a provisioning tool wrote nothing to the file.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/e5fbd308c842acfc. Report an issue: GitHub.