SonarSource/sonarqube · error · IllegalStateException
Sign requests is enabled but SonarQube private key and/or So
Error message
Sign requests is enabled but SonarQube private key and/or SonarQube certificate is missing
What it means
addSignRequestFieldsIfNecessary() checks that both the SonarQube SP private key and certificate are configured. When either is missing AND 'Sign requests' (sonar.auth.saml.signatureEnabled) is enabled, SAML request signing cannot be set up on the RelyingPartyRegistration, so it throws IllegalStateException with this message.
Source
Thrown at server/sonar-auth-saml/src/main/java/org/sonar/auth/saml/SonarqubeRelyingPartyRegistrationRepository.java:93
} catch (MalformedURLException | URISyntaxException | IllegalArgumentException e) {
throw new IllegalStateException("Invalid SAML Login URL", e);
}
}
private void addSignRequestFieldsIfNecessary(RelyingPartyRegistration.Builder builder) {
//(on SQ) to sign request we need SP private key and certificate
//(on IDP) to verify request IDP needs SP public key (certificate)
//(on IDP) to sign response we need IDP private key (embedded)
//(on SQ) to verify response we need IDP public key (certificate) !mandatory!
//(on IDP) encryption: we need SP public key (certificate)
//(on SQ) decryption: we need Service Provide private key and certificate
Optional<String> serviceProviderPrivateKey = samlSettings.getServiceProviderPrivateKey();
if (serviceProviderPrivateKey.isEmpty() || samlSettings.getServiceProviderCertificate() == null) {
if (samlSettings.isSignRequestsEnabled()) {
throw new IllegalStateException("Sign requests is enabled but SonarQube private key and/or SonarQube certificate is missing");
}
return;
}
String privateKeyString = serviceProviderPrivateKey.get();
String serviceProviderCertificateString = samlSettings.getServiceProviderCertificate();
PrivateKey privateKey = samlPrivateKeyConverter.toPrivateKey(privateKeyString);
X509Certificate spX509Certificate = samlCertificateConverter.toX509Certificate(serviceProviderCertificateString);
builder.decryptionX509Credentials(c -> c.add(Saml2X509Credential.decryption(privateKey, spX509Certificate)));
if (samlSettings.isSignRequestsEnabled()) {
builder.signingX509Credentials(c -> c.add(Saml2X509Credential.signing(privateKey, spX509Certificate)));
}
}
@VisibleForTesting
SamlSettings getSamlSettings() {
return samlSettings;View on GitHub (pinned to 184c821202)
Solutions
- Upload BOTH sonar.auth.saml.privateKey (PKCS#8) and sonar.auth.saml.certificate in the SAML settings, then restart the analysis/reload settings
- If you do not need request signing, set sonar.auth.saml.signatureEnabled=false (or uncheck 'Sign requests')
- Re-export the key pair: openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem, convert key to PKCS#8, and store both values
Example fix
// before: signing enabled with no key sonar.auth.saml.signatureEnabled=true // after: provide both parts sonar.auth.saml.signatureEnabled=true sonar.auth.saml.privateKey=MIIEvQIBADANBgkq... sonar.auth.saml.certificate=MIIDdzCCAl+gAwIBAg...
Defensive patterns
Strategy: validation
Validate before calling
boolean signingOn = Boolean.parseBoolean(settings.get("sonar.auth.saml.signatureEnabled"));
boolean keyPresent = settings.get("sonar.auth.saml.privateKey") != null && !settings.get("sonar.auth.saml.privateKey").isBlank();
boolean certPresent = settings.get("sonar.auth.saml.certificate") != null && !settings.get("sonar.auth.saml.certificate").isBlank();
if (signingOn && !(keyPresent && certPresent)) {
throw new ConfigurationException("Sign requests requires BOTH privateKey and certificate");
} Type guard
static boolean samlSigningConfigComplete(SamlSettings s) {
return !s.isSignRequestsEnabled() || (s.getServiceProviderPrivateKey().isPresent() && s.getServiceProviderCertificate() != null);
} Try / catch
try {
registration = repo.findByRegistrationId("sonarqube");
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Sign requests is enabled")) {
throw new ConfigurationException("Upload SP key+cert or disable sonar.auth.saml.signatureEnabled");
}
throw e;
} Prevention
- Before toggling 'Sign requests' on, upload both the PKCS#8 private key and the X.509 certificate
- Generate key+cert together: openssl req -x509 -newkey rsa:2048 -nodes
- After SonarQube upgrades, re-verify SAML settings persisted correctly
- If signing is not required by your IdP, keep sonar.auth.saml.signatureEnabled=false
When it happens
Trigger: findByRegistrationId() builds the SAML registration while sonar.auth.saml.signatureEnabled=true but getServiceProviderPrivateKey() returns empty or getServiceProviderCertificate() returns null — i.e. signing was toggled on without uploading both the key and the certificate.
Common situations: Admins enabling 'Sign requests' in the SAML settings form but leaving the privateKey/certificate fields empty, configuring only the certificate (or only the key), or losing stored key settings after a SonarQube upgrade/migration.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Configuration is not complete : %s
- Invalid certificate
- Error while loading PKCS8 private key, please check the form
- Invalid SAML Login URL
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/cad51f39d4e65cad.
Report an issue: GitHub.