apereo/cas · error
invalid_request
invalid_request
Error message
CAS cannot accept the request given the issuer is invalid.
What it means
OidcVerifiableCredentialNonceEndpointController.handle issues a credential nonce (c_nonce) for verifiable credential issuance, but first validates the request issuer. If issuerService.validateIssuer fails for the VC nonce URL, the controller responds HTTP 400 'invalid_request' / 'Invalid issuer' instead of a nonce.
Solutions
- Call the nonce endpoint on the URL matching cas.authn.oidc.issuer exactly.
- Enable proper forwarded-header handling so validateIssuer sees the original scheme/host.
- Verify the issuer configuration includes the path prefix used by the deployment.
Example fix
// before curl -X POST http://localhost:8443/cas/oidc/vc/nonce // after curl -X POST https://sso.example.org/cas/oidc/vc/nonce
Defensive patterns
Strategy: validation
Validate before calling
String nonceUrl = issuer + "/vc/nonce"; // derive from issuer
if (!URI.create(nonceUrl).getHost().equals(URI.create(issuer).getHost())) {
throw new IllegalArgumentException("Nonce endpoint must be on the issuer host");
} Try / catch
if (resp.status() == 400 && body.contains("Invalid issuer")) {
throw new IllegalStateException("Call the nonce endpoint via the configured issuer URL");
} Prevention
- Construct wallet callback URLs from the issuer, not from internal hostnames
- Keep scheme consistent (https) end to end
- Test nonce issuance through the same ingress path production clients use
When it happens
Trigger: POST/GET to the VC nonce endpoint (VC_NONCE_URL) from a host/origin that does not match the configured OIDC issuer.
Common situations: Wallet callbacks hitting an internal hostname; misconfigured issuer path; load balancer terminating TLS and changing the scheme seen by CAS.
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
- Proof nonce is invalid or missing
- invalid_request
- invalid_request
- invalid_request
- Missing required principal attribute for claim
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/4a38fbba7708b707.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-oidc-vc/src/main/java/org/apereo/cas/oidc/vc/issuer/web/OidcVerifiableCredentialNonceEndpointController.java:60
/**
* Handle response entity.
*
* @param httpRequest the http request
* @param httpResponse the http response
* @return the response entity
*/
@PostMapping(value = {
'/' + OidcConstants.BASE_OIDC_URL + '/' + OidcConstants.VC_NONCE_URL,
"/**/" + OidcConstants.VC_NONCE_URL
}, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity handle(
final HttpServletRequest httpRequest,
final HttpServletResponse httpResponse) {
val webContext = new JEEContext(httpRequest, httpResponse);
if (!getConfigurationContext().getIssuerService().validateIssuer(webContext, List.of(OidcConstants.VC_NONCE_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 nonce = credentialNonceService.create();
return ResponseEntity
.ok()
.body(Map.of(OidcConstants.C_NONCE, nonce.value(), OidcConstants.C_NONCE_EXPIRES_IN, nonce.expiresIn()));
}
/**
* Handle errors.
*
* @param ex the ex
* @return the response entity
*/
@ExceptionHandler(Exception.class)
@SuppressWarnings("UnusedMethod")
private static ResponseEntity<String> handle(final Exception ex) {View on GitHub (pinned to e7288fc434)