{"record":{"id":"3f8fb39bb225582d","repo":"SonarSource/sonarqube","slug":"fail-to-generate-secret-key","errorCode":null,"errorMessage":"Fail to generate secret key","messagePattern":"Fail to generate secret key","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sonar-plugin-api-impl/src/main/java/org/sonar/api/config/internal/AesCipher.java","lineNumber":91,"sourceCode":"    if (!file.exists() || !file.isFile()) {\n      throw new IllegalStateException(\"The property \" + ENCRYPTION_SECRET_KEY_PATH + \" does not link to a valid file: \" + path);\n    }\n    String s = FileUtils.readFileToString(file, UTF_8);\n    if (StringUtils.isBlank(s)) {\n      throw new IllegalStateException(\"No secret key in the file: \" + path);\n    }\n    return new SecretKeySpec(Base64.decodeBase64(StringUtils.trim(s)), CRYPTO_KEY);\n  }\n\n  String generateRandomSecretKey() {\n    try {\n      KeyGenerator keyGen = KeyGenerator.getInstance(CRYPTO_KEY);\n      keyGen.init(KEY_SIZE_IN_BITS, new SecureRandom());\n      SecretKey secretKey = keyGen.generateKey();\n      return Base64.encodeBase64String(secretKey.getEncoded());\n\n    } catch (Exception e) {\n      throw new IllegalStateException(\"Fail to generate secret key\", e);\n    }\n  }\n\n  String getPathToSecretKey() {\n    if (StringUtils.isBlank(pathToSecretKey)) {\n      pathToSecretKey = new File(FileUtils.getUserDirectoryPath(), \".sonar/sonar-secret.txt\").getPath();\n    }\n    return pathToSecretKey;\n  }\n\n  public void setPathToSecretKey(@Nullable String pathToSecretKey) {\n    this.pathToSecretKey = pathToSecretKey;\n  }\n}\n","sourceCodeStart":73,"sourceCodeEnd":106,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/sonar-plugin-api-impl/src/main/java/org/sonar/api/config/internal/AesCipher.java#L73-L106","documentation":"AesCipher.generateRandomSecretKey builds an AES secret key via KeyGenerator and Base64-encodes it. Any failure while obtaining, initializing, or generating the key is wrapped in this IllegalStateException. The library throws it because a random secret key is fundamental to encrypted settings and should never silently fail.","triggerScenarios":"Calling generateRandomSecretKey() when the JVM's crypto provider cannot supply the 'AES' KeyGenerator, KEY_SIZE_IN_BITS is not supported by the installed JCE provider, or SecureRandom instantiation/entropy fails.","commonSituations":"Running on a restricted JVM or stripped-down JRE lacking the AES provider; FIPS-enabled environments rejecting the key size; low entropy on headless servers blocking SecureRandom; corrupted JCE policy files.","solutions":["Verify the JVM includes a standard JCE provider supporting AES with the requested key size (use a full JDK/JRE)","Check that the configured key size (typically 128 bits) is allowed by local crypto policy (e.g. FIPS restrictions)","Rule out entropy starvation on headless Linux by configuring -Djava.security.egd=file:/dev/urandom","Upgrade the SonarQube plugin API / JRE to a supported combination"],"exampleFix":"// before\nSecretKey key = AesCipher.generateRandomSecretKey();\n// after\ntry {\n  SecretKey key = AesCipher.generateRandomSecretKey();\n} catch (IllegalStateException e) {\n  // inspect e.getCause(): provider/key-size problem\n}","handlingStrategy":"try-catch","validationCode":"// check AES support before generating\ntry {\n  javax.crypto.KeyGenerator.getInstance(\"AES\");\n} catch (java.security.NoSuchAlgorithmException e) {\n  throw new RuntimeException(\"JVM lacks AES KeyGenerator provider\", e);\n}","typeGuard":null,"tryCatchPattern":"try {\n  SecretKey key = AesCipher.generateRandomSecretKey();\n} catch (IllegalStateException e) {\n  log.error(\"Key generation failed: {}\", e.getCause());\n  throw new ConfigurationException(\"Unable to generate encryption secret key\", e);\n}","preventionTips":["Use a full JDK with default JCE providers","Keep key size at provider-supported values (128 bits)","Configure adequate entropy on headless servers (java.security.egd)","Pin supported JRE versions in deployment docs"],"tags":["crypto","jvm","configuration"],"backgroundTag":"internal-invariant-violation","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}