SonarSource/sonarqube · error · IllegalArgumentException
Error while loading PKCS8 private key, please check the form
Error message
Error while loading PKCS8 private key, please check the format
What it means
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.
Source
Thrown at server/sonar-auth-saml/src/main/java/org/sonar/auth/saml/SamlPrivateKeyConverter.java:42
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import org.sonar.api.server.ServerSide;
@ServerSide
class SamlPrivateKeyConverter {
PrivateKey toPrivateKey(String privateKeyString) {
String cleanedPrivateKeyString = sanitizePrivateKeyString(privateKeyString);
byte[] decoded = Base64.getDecoder().decode(cleanedPrivateKeyString);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new IllegalArgumentException("Error while loading PKCS8 private key, please check the format", e);
}
}
private static String sanitizePrivateKeyString(String privateKeyString) {
return privateKeyString
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s+", "");
}
}
View on GitHub (pinned to 184c821202)
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-----'
Example fix
// before (PKCS#1 key, rejected) // -----BEGIN RSA PRIVATE KEY----- // MIIEpAIBAAKCAQEA... // after: convert first // $ openssl pkcs8 -topk8 -nocrypt -in key.pem -out key-pkcs8.pem String pkcs8Key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...";
Defensive patterns
Strategy: validation
Validate before calling
String cleaned = key.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replaceAll("\\s", "");
if (cleaned.contains("RSA PRIVATE")) throw new IllegalStateException("PKCS#1 key detected; convert with openssl pkcs8 -topk8 -nocrypt");
byte[] decoded = Base64.getDecoder().decode(cleaned);
new PKCS8EncodedKeySpec(decoded); // throws InvalidKeySpecException later at KeyFactory if wrong Type guard
static boolean isPkcs8Header(String pem) {
return pem != null && pem.contains("-----BEGIN PRIVATE KEY-----");
} Try / catch
try {
PrivateKey key = SamlPrivateKeyConverter.toPrivateKey(cfg.privateKey());
} catch (IllegalArgumentException e) {
log.error("SAML private key must be PKCS#8, unencrypted", e);
throw new ConfigurationException("Re-export key: openssl pkcs8 -topk8 -nocrypt -in key.pem");
} Prevention
- 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`
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid certificate
- Invalid SAML Login URL
- Failed to decode Github Application private key
- The Github App private key is not valid
- Sign requests is enabled but SonarQube private key and/or So
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/a1b91140c8e52822.
Report an issue: GitHub.