apereo/cas · error
invalid_request
invalid_request
Error message
CAS cannot accept the request given the issuer is invalid.
What it means
OidcVerifiableCredentialIssuerMetadataController.handle serves the well-known OpenID credential issuer metadata document only when the request's issuer matches the configured OIDC issuer. On mismatch it returns HTTP 400 with error 'invalid_request' and 'Invalid issuer'.
Solutions
- Discover metadata using the issuer identifier URL exactly as configured in CAS.
- Fix proxy configuration to preserve the Host header (or set forwarded-header handling in CAS).
- Align cas.authn.oidc.issuer with the externally visible base URL.
Example fix
// before curl http://internal-host:8080/cas/oidc/.well-known/openid-credential-issuer // after curl https://sso.example.org/cas/oidc/.well-known/openid-credential-issuer
Defensive patterns
Strategy: validation
Validate before calling
// Discover via issuer identifier
URI wellKnown = URI.create(issuer + "/.well-known/openid-credential-issuer");
if (!wellKnown.getHost().equals(URI.create(issuer).getHost())) {
throw new IllegalArgumentException("Issuer host mismatch");
} Try / catch
if (resp.status() == 400 && body.contains("Invalid issuer")) {
throw new IllegalStateException("Metadata discovery must use the configured issuer URL");
} Prevention
- Fetch metadata from the exact issuer value in the client configuration
- Avoid switching hostnames (localhost vs FQDN) between environments
- Enable forwarded header support on CAS behind TLS-terminating proxies
When it happens
Trigger: GET /oidc/.well-known/openid-credential-issuer (WELL_KNOWN_OPENID_CREDENTIAL_ISSUER_URL) with a Host/URL that does not match cas.authn.oidc.issuer per issuerService.validateIssuer.
Common situations: Wallet/client discovering metadata via a different hostname or port than the configured issuer; reverse proxy not forwarding the original host; environment (dev vs prod) issuer mismatch.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- invalid_request
- invalid_request
- invalid_request
- Missing required principal attribute for claim
- Proof nonce is invalid or missing
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/d102813d95f2d041.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-oidc-vc/src/main/java/org/apereo/cas/oidc/vc/issuer/web/OidcVerifiableCredentialIssuerMetadataController.java:56
/**
* Handle response entity.
*
* @param request the request
* @param response the response
* @return the response entity
*/
@GetMapping(value = {
'/' + OidcConstants.BASE_OIDC_URL + '/' + OidcConstants.WELL_KNOWN_OPENID_CREDENTIAL_ISSUER_URL,
"/**/" + OidcConstants.WELL_KNOWN_OPENID_CREDENTIAL_ISSUER_URL
}, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Handle OIDC credential issuer metadata request",
description = "Handles requests for well-known OIDC credential issuer metadata")
public ResponseEntity handle(final HttpServletRequest request,
final HttpServletResponse response) {
val webContext = new JEEContext(request, response);
if (!getConfigurationContext().getIssuerService().validateIssuer(webContext, List.of(OidcConstants.WELL_KNOWN_OPENID_CREDENTIAL_ISSUER_URL))) {
LOGGER.warn("CAS cannot accept the request given the issuer is invalid.");
val body = OAuth20Utils.getErrorResponseBody(OAuth20Constants.INVALID_REQUEST, "Invalid issuer");
return ResponseEntity.badRequest().body(body);
}
val body = metadataService.build();
return ResponseEntity.ok().body(body);
}
}
View on GitHub (pinned to e7288fc434)