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

  1. Discover metadata using the issuer identifier URL exactly as configured in CAS.
  2. Fix proxy configuration to preserve the Host header (or set forwarded-header handling in CAS).
  3. 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

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


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)