apereo/cas · warning

Unable to resolve SignatureSigningParameters, response…

Error message

Unable to resolve SignatureSigningParameters, response signing will fail. Make sure domain names in IDP metadata URLs and certificates match CAS domain name

What it means

CAS failed to compute SignatureSigningParameters for the SAML response, meaning the resolved signing credential (from the IdP metadata / keystore matching the configured entityID and domain) was null. The response will be produced unsigned or signing will fail. The message hints that the IDP metadata URLs and the configured certificates must be on the CAS server's own domain so credentials can be resolved.

Solutions

  1. Verify cas.authn.saml-idp.signing properties: keystore path, keystore password, private key alias and password point to a valid, loadable key.
  2. Ensure the IdP metadata location/entityID hostname matches the CAS domain (or the domain CAS expects); re-encode/rebuild IdP metadata if hosts were renamed.
  3. Confirm the signing certificate is present, unexpired, and the alias exists in the keystore (list with keytool -list -keystore ...).
  4. Check the SamlRegisteredService/IdP metadata actually declares the KeyDescriptor with signing use that CAS resolves for the response.
  5. Enable DEBUG logging on org.apereo.cas.support.saml and OpenSAML to see why the credential resolver returned empty.

Example fix

// before: signing keystore misconfigured
# cas.authn.saml-idp.signing.key-store=classpath:wrong-keystore.jceks
# cas.authn.saml-idp.signing.private-key-alias=old-idp
// after: valid keystore and alias matching the IdP metadata hostname
# cas.authn.saml-idp.signing.key-store=file:/etc/cas/saml-idp/idp-signing.jceks
# cas.authn.saml-idp.signing.private-key-alias=idp.example.edu
# cas.authn.saml-idp.signing.private-key-password=changeit
Defensive patterns

Strategy: validation

Validate before calling

// Startup-time guard: ensure the IdP signing credential resolves
val credential = casKeystoreHandler.resolveSigningKey signingCredential(...);
Objects.requireNonNull(credential, "SAML IdP signing credential unavailable — check keystore config and metadata hostname");

Type guard

boolean signingConfigured(SamlIdPProperties p) { return p.getSigning().getKeyStore() != null && p.getSigning().getPrivateKeyAlias() != null; }

Try / catch

try {
    val params = signer.buildSignatureSigningParameters();
} catch (Exception e) {
    LOGGER.error("Cannot resolve SignatureSigningParameters — check keystore + IdP metadata domain", e);
    throw new IllegalStateException("SAML response signing unavailable", e); // fail fast, don't emit unsigned
}

Prevention

When it happens

Trigger: buildSignatureSigningParameters (via the OpenSAML SignatureSigningParametersResolver) returns no parameters — typically when SamlIdPObjectSigner cannot resolve the IdP's signing credential because the entityID in the IdP metadata resolves via a URL whose host differs from the CAS domain, or the signing keystore/certificate config (e.g. cas.authn.saml-idp.signing.*) is misconfigured or the key is unavailable.

Common situations: IdP metadata configured with an external hostname not matching the CAS domain so credential lookup fails; signing keystore path/password wrong; self-signed or expired certificate not loaded; signing key defined for a different entityID than the one CAS presents; multi-tenant setups where metadata hostnames diverge after a DNS/proxy change.

Understand the failure class

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/846b297ca36c539b. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/profile/builders/enc/DefaultSamlIdPObjectSigner.java:224

            criteria.add(new SignatureSigningConfigurationCriterion(signatureSigningConfiguration));
            criteria.add(new RoleDescriptorCriterion(descriptor));

            val resolver = new SAMLMetadataSignatureSigningParametersResolver();
            LOGGER.trace("Resolving signature signing parameters for [{}]", descriptor.getElementQName().getLocalPart());
            val params = resolver.resolveSingle(criteria);
            if (params != null) {
                LOGGER.trace("""
                        Created signature signing parameters.
                        Signature algorithm: [{}]
                        Signature canonicalization algorithm: [{}]
                        Signature reference digest methods: [{}]
                        Signature reference canonicalization algorithm: [{}]""",
                    params.getSignatureAlgorithm(),
                    params.getSignatureCanonicalizationAlgorithm(),
                    params.getSignatureReferenceDigestMethod(),
                    params.getSignatureReferenceCanonicalizationAlgorithm());
            } else {
                LOGGER.warn("Unable to resolve SignatureSigningParameters, response signing will fail."
                    + " Make sure domain names in IDP metadata URLs and certificates match CAS domain name");
            }
            return params;
        });
    }

    /**
     * Gets signature signing configuration.
     * The resolved used is {@link SamlIdPMetadataCredentialResolver} that
     * allows the entire criteria set to be passed to the role descriptor resolver.
     * This behavior allows the passing of {@link SamlIdPSamlRegisteredServiceCriterion}
     * so signing configuration, etc can be fetched for a specific service as an override,
     * if on is in fact defined for the service.
     *
     * @param service the service
     * @return the signature signing configuration
     * @throws Throwable the throwable
     */

View on GitHub (pinned to e7288fc434)