{"record":{"id":"a1b91140c8e52822","repo":"SonarSource/sonarqube","slug":"error-while-loading-pkcs8-private-key-please-chec","errorCode":null,"errorMessage":"Error while loading PKCS8 private key, please check the format","messagePattern":"Error while loading PKCS8 private key, please check the format","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server/sonar-auth-saml/src/main/java/org/sonar/auth/saml/SamlPrivateKeyConverter.java","lineNumber":42,"sourceCode":"import java.security.PrivateKey;\nimport java.security.spec.InvalidKeySpecException;\nimport java.security.spec.PKCS8EncodedKeySpec;\nimport java.util.Base64;\nimport org.sonar.api.server.ServerSide;\n\n@ServerSide\nclass SamlPrivateKeyConverter {\n\n  PrivateKey toPrivateKey(String privateKeyString) {\n    String cleanedPrivateKeyString = sanitizePrivateKeyString(privateKeyString);\n\n    byte[] decoded = Base64.getDecoder().decode(cleanedPrivateKeyString);\n    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);\n    try {\n      KeyFactory keyFactory = KeyFactory.getInstance(\"RSA\");\n      return keyFactory.generatePrivate(keySpec);\n    } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {\n      throw new IllegalArgumentException(\"Error while loading PKCS8 private key, please check the format\", e);\n    }\n  }\n\n  private static String sanitizePrivateKeyString(String privateKeyString) {\n    return privateKeyString\n      .replace(\"-----BEGIN PRIVATE KEY-----\", \"\")\n      .replace(\"-----END PRIVATE KEY-----\", \"\")\n      .replaceAll(\"\\\\s+\", \"\");\n  }\n}\n","sourceCodeStart":24,"sourceCodeEnd":53,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-auth-saml/src/main/java/org/sonar/auth/saml/SamlPrivateKeyConverter.java#L24-L53","documentation":"SamlPrivateKeyConverter.toPrivateKey() decodes a Base64 string as PKCS#8 DER and generates an RSA PrivateKey via KeyFactory. If KeyFactory.getInstance(\"RSA\") or generatePrivate throws NoSuchAlgorithmException or InvalidKeySpecException, the key bytes are not a valid PKCS#8-encoded RSA private key and it throws IllegalArgumentException with this message.","triggerScenarios":"Calling toPrivateKey() (or configuring sonar.auth.saml.privateKey) with a key that is PKCS#1 ('BEGIN RSA PRIVATE KEY'), OpenSSL 'BEGIN PRIVATE KEY' with an EC/other algorithm, encrypted ('BEGIN ENCRYPTED PRIVATE KEY'), truncated, or otherwise not PKCS#8 RSA DER after the PEM header is stripped.","commonSituations":"Admins exporting keys with 'openssl genrsa' (PKCS#1) instead of 'openssl genpkey' (PKCS#8), pasting the IdP certificate instead of the SP key, or including header/footer lines that break Base64 decoding.","solutions":["Convert the key to PKCS#8: openssl pkcs8 -topk8 -nocrypt -in key.pem -out key-pkcs8.pem, then paste only the Base64 body into sonar.auth.saml.privateKey","If the key is PKCS#1, the header 'BEGIN RSA PRIVATE KEY' is the tell — re-export as 'BEGIN PRIVATE KEY' (PKCS#8)","Confirm the header/footer lines are removed; the converter strips exactly '-----BEGIN PRIVATE KEY-----'/'-----END PRIVATE KEY-----'"],"exampleFix":"// before (PKCS#1 key, rejected)\n// -----BEGIN RSA PRIVATE KEY-----\n// MIIEpAIBAAKCAQEA...\n// after: convert first\n// $ openssl pkcs8 -topk8 -nocrypt -in key.pem -out key-pkcs8.pem\nString pkcs8Key = \"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...\";","handlingStrategy":"validation","validationCode":"String cleaned = key.replace(\"-----BEGIN PRIVATE KEY-----\", \"\").replace(\"-----END PRIVATE KEY-----\", \"\").replaceAll(\"\\\\s\", \"\");\nif (cleaned.contains(\"RSA PRIVATE\")) throw new IllegalStateException(\"PKCS#1 key detected; convert with openssl pkcs8 -topk8 -nocrypt\");\nbyte[] decoded = Base64.getDecoder().decode(cleaned);\nnew PKCS8EncodedKeySpec(decoded); // throws InvalidKeySpecException later at KeyFactory if wrong","typeGuard":"static boolean isPkcs8Header(String pem) {\n  return pem != null && pem.contains(\"-----BEGIN PRIVATE KEY-----\");\n}","tryCatchPattern":"try {\n  PrivateKey key = SamlPrivateKeyConverter.toPrivateKey(cfg.privateKey());\n} catch (IllegalArgumentException e) {\n  log.error(\"SAML private key must be PKCS#8, unencrypted\", e);\n  throw new ConfigurationException(\"Re-export key: openssl pkcs8 -topk8 -nocrypt -in key.pem\");\n}","preventionTips":["Always convert keys to PKCS#8 before pasting: openssl pkcs8 -topk8 -nocrypt","Reject 'BEGIN RSA PRIVATE KEY' (PKCS#1) keys up front","Never paste encrypted ('BEGIN ENCRYPTED PRIVATE KEY') keys — decrypt first","Confirm the key and certificate form a matching pair: `openssl x509 -noout -modulus` vs `openssl rsa -noout -modulus`"],"tags":["saml","private-key","pkcs8","config"],"backgroundTag":"invalid-argument-format","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"}