hashicorp/nomad · error
failed to retrieve OIDC provider metadata
Error message
failed to retrieve OIDC provider metadata: %w
What it means
During OIDCCompleteAuth, Nomad reads provider metadata via oidcProvider.Claims to see whether the IdP supports the authorization_response_iss parameter. If the underlying library fails to extract those claims from the cached provider's discovery data, the error is wrapped as 'failed to retrieve OIDC provider metadata'.
Solutions
- Inspect the wrapped error for the underlying decode/claim failure.
- Fetch <discovery-url>/.well-known/openid-configuration with curl and validate the JSON fields.
- Fix or replace the non-compliant IdP discovery endpoint (or upgrade the IdP to a compliant version).
- Clear any stale provider state by restarting the login flow after correcting the discovery URL/config.
Example fix
// before: discovery URL points at an app that returns HTML
config := &api.ACLAuthMethodConfig{OIDCDiscoveryURL: "https://idp.example.com/app"}
// after: point at the real OIDC discovery root
config := &api.ACLAuthMethodConfig{OIDCDiscoveryURL: "https://idp.example.com/realms/main"} Defensive patterns
Strategy: fallback
Validate before calling
resp, err := http.Get(discoveryURL + "/.well-known/openid-configuration")
if err != nil { return err }
var doc map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&doc); err != nil {
return fmt.Errorf("discovery doc is not valid JSON: %w", err)
}
log.Printf("iss parameter support: %v", doc["authorization_response_iss_parameter_supported"]) Type guard
func looksLikeOIDCDiscovery(body []byte) bool {
var m map[string]interface{}
if json.Unmarshal(body, &m) != nil { return false }
_, hasIssuer := m["issuer"]
_, hasAuthEp := m["authorization_endpoint"]
return hasIssuer && hasAuthEp
} Try / catch
_, _, err := client.ACL().GetOIDCCompleteAuth(req, nil)
if err != nil && strings.Contains(err.Error(), "failed to retrieve OIDC provider metadata") {
return fmt.Errorf("IdP discovery document incomplete/non-compliant; validate %s/.well-known/openid-configuration: %w", discoveryURL, err)
} Prevention
- Validate the discovery document JSON after configuring a new auth method
- Use a standards-compliant IdP (Keycloak/Okta/Auth0) behind stable endpoints
- Check proxies don't modify or truncate .well-known responses
- Retry the login flow if a transient network error corrupted provider metadata
When it happens
Trigger: Calling OIDCCompleteAuth when the provider's discovery document lacks or fails to decode the expected claims — malformed/partial .well-known/openid-configuration, a provider object that could not fully load metadata, or library decode errors.
Common situations: IdP behind a proxy that truncates or mangles the discovery document; non-standard OIDC implementation with incomplete metadata; transient network failure during provider construction earlier in the flow.
Related errors
- failed to generate auth URL
- failed to generate OIDC provider
- ACL auth method not found
- ACL binding rule not found
- all servers should be running version
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/a74764e290d99262.
Report an issue: GitHub.
Appendix: source
Thrown at nomad/acl_endpoint.go:2776
if done, err := a.srv.forward(structs.ACLOIDCCompleteAuthRPCMethod, args, args, reply); done {
return err
}
}
// Use the cache to provide us with an OIDC provider for the auth method
// that was resolved from state.
oidcProvider, err := a.oidcProviderCache.Get(authMethod)
if err != nil {
return fmt.Errorf("failed to generate OIDC provider: %v", err)
}
// Check if the OIDC provider requires the `iss` parameter to be
// validated
providerMetadata := struct {
AuthorizationResponseIssParameterSupported bool `json:"authorization_response_iss_parameter_supported"`
}{}
if err := oidcProvider.Claims(&providerMetadata); err != nil {
return fmt.Errorf("failed to retrieve OIDC provider metadata: %w", err)
}
if providerMetadata.AuthorizationResponseIssParameterSupported {
if args.Iss == "" || args.Iss != authMethod.Config.OIDCDiscoveryURL {
return errors.New("invalid or missing issuer parameter in callback")
}
}
// Retrieve the request generated in OIDCAuthURL()
oidcReq := a.oidcRequestCache.LoadAndDelete(args.ClientNonce) // I am so done with this NONCENSE
if oidcReq == nil {
// note: this may happen if there is a leader election between getting
// the auth url and completing the login flow here.
return errors.New("no OIDC request found for client nonce")
}
// Generate a context with a deadline. This is passed to the OIDC provider
// and used when making remote HTTP requests.
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(aclOIDCCallbackRequestExpiryTime))View on GitHub (pinned to 482b49bf1a)