hashicorp/nomad · error
no auth method config or client assertion
Error message
no auth method config or client assertion
What it means
BuildClientAssertionJWT returns this error when the ACLAuthMethodConfig is nil or has no OIDCClientAssertion configured. A client-assertion JWT cannot be built without the private-key/JWKS/derived-key assertion settings, and the function refuses to proceed.
Source
Thrown at lib/auth/oidc/client_assertion.go:57
// - "client_secret": uses the config's ClientSecret as an HMAC key to sign
// the JWT. This is marginally more secure than a bare ClientSecret, as the
// JWT is time-bound, and signed by the secret rather than sending the
// secret itself over the network.
// - "nomad": uses the RS256 nomadKey (Nomad's private key) to sign the JWT,
// and the nomadKID as the JWT's "kid" header, which the OIDC provider uses
// to find the public key at Nomad's JWKS endpoint (/.well-known/jwks.json)
// to verify the JWT signature. This is arguably the most secure option,
// because only Nomad has the private key.
// - "private_key": uses an RSA private key provided by the user. They may
// provide a KeyID to use as the JWT's "kid" header, or an x509 public
// certificate to derive an x5t#S256 (or x5t) header, which the OIDC
// provider uses to find the cert on their end to verify the JWT signature.
// This is the most flexible option, allowing users to manage their own
// keys however they like.
func BuildClientAssertionJWT(config *structs.ACLAuthMethodConfig, nomadKey *rsa.PrivateKey, nomadKID string) (*cass.JWT, error) {
// should already be validated by caller, but just in case.
if config == nil || config.OIDCClientAssertion == nil {
return nil, errors.New("no auth method config or client assertion")
}
// this is all we use config for
clientID := config.OIDCClientID
// client assertion-specific info is in here
as := config.OIDCClientAssertion
// this should have also happened long before, but again, just in case.
if err := as.Validate(); err != nil {
return nil, err
}
opts := []cass.Option{
cass.WithHeaders(as.ExtraHeaders),
}
switch as.KeySource {
View on GitHub (pinned to 482b49bf1a)
Solutions
- Configure OIDCClientAssertion (with key source: private key, JWKS, or derived key) on the ACL auth method before enabling private_key_jwt
- Verify the auth method's config is loaded and non-nil before building the assertion
- If the provider uses client_secret auth instead, do not use the client assertion path
- Re-check the ACL auth method after any config update that may have cleared the assertion settings
Example fix
// before: missing assertion config
authMethodConfig := &structs.ACLAuthMethodConfig{
OIDCClientID: "nomad",
}
jwt, err := auth.BuildClientAssertionJWT(authMethodConfig, key, kid) // errors
// after: configure the assertion
authMethodConfig := &structs.ACLAuthMethodConfig{
OIDCClientID: "nomad",
OIDCClientAssertion: &structs.OIDCClientAssertion{KeySource: "nomad", ...},
}
jwt, err := auth.BuildClientAssertionJWT(authMethodConfig, key, kid) Defensive patterns
Strategy: validation
Validate before calling
if config == nil || config.OIDCClientAssertion == nil {
// fall back to client_secret auth or configure assertion first
return errors.New("auth method lacks OIDC client assertion; cannot use private_key_jwt")
} Type guard
func hasClientAssertion(c *structs.ACLAuthMethodConfig) bool {
return c != nil && c.OIDCClientAssertion != nil
} Try / catch
jwt, err := auth.BuildClientAssertionJWT(config, key, kid)
if err != nil && strings.Contains(err.Error(), "no auth method config or client assertion") {
return configureAssertionThenRetry()
} Prevention
- Validate the ACL auth method config on create/update so assertion settings are required when the provider uses private_key_jwt
- Check hasClientAssertion before choosing the client-assertion auth flow
- Keep auth method configs in version control to catch accidental clearing
- Match the assertion style (private key / JWKS / derived key) to what the OIDC provider documents
When it happens
Trigger: Calling BuildClientAssertionJWT with config == nil, or config.OIDCClientAssertion == nil — i.e. the auth method is not configured for OIDC client assertion (private_key_jwt).
Common situations: OIDC auth method configured without BoundAudiences/ClientAssertion while the OIDC provider requires private_key_jwt; calling the assertion builder for auth methods using a different client authentication style (client_secret); config dropped or overwritten in the ACL auth method update.
Related errors
- missing Audience
- PrivateKey is required for `private_key` KeySource
- invalid KeyIDHeader
- missing login token
- failed to login with JWT: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/9d1cb30425e5a756.
Report an issue: GitHub.