hashicorp/nomad · error

invalid client assertion config: %w

Error message

invalid client assertion config: %w

What it means

For Type=OIDC, ACLAuthMethod Config validation wraps any error from a.OIDCClientAssertion.Validate() as "invalid client assertion config: %w". The nested OIDCClientAssertion (private-key JWT client authentication) has a required field missing or malformed.

Source

Thrown at nomad/structs/acl.go:1591

	}
}

func (a *ACLAuthMethodConfig) Validate(methodType string) error {
	if a == nil {
		return errors.New("missing auth method Config")
	}
	mErr := &multierror.Error{}

	switch methodType {
	case ACLAuthMethodTypeOIDC:
		if a.OIDCDiscoveryURL == "" {
			mErr = multierror.Append(mErr, errors.New("missing OIDCDiscoveryURL"))
		}
		if a.OIDCClientID == "" {
			mErr = multierror.Append(mErr, errors.New("missing OIDCClientID"))
		}
		if err := a.OIDCClientAssertion.Validate(); err != nil {
			mErr = multierror.Append(mErr, fmt.Errorf("invalid client assertion config: %w", err))
		}

	case ACLAuthMethodTypeJWT:
		if a.OIDCDiscoveryURL == "" && a.JWKSURL == "" && len(a.JWTValidationPubKeys) == 0 {
			mErr = multierror.Append(mErr, errors.New(
				"JWT auth method requires either OIDCDiscoveryURL, or JWKS URL, or JWTValidationPubKeys set"),
			)
		}
	}

	return helper.FlattenMultierror(mErr)
}

func (a *ACLAuthMethodConfig) Copy() *ACLAuthMethodConfig {
	if a == nil {
		return nil
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Read the wrapped inner error and supply the missing assertion field (KeySource, KeyFile, KeyID, ClientID, etc.).
  2. If private-key JWT is not needed, remove the OIDCClientAssertion block entirely so plain client-secret auth is used.
  3. Verify the referenced key file exists on Nomad servers and is a parseable PEM/DER key.
  4. Test the assertion config with the IdP docs' required claims before re-submitting.

Example fix

// before
Config.OIDCClientAssertion = &structs.OIDCClientAssertion{ClientID: "nomad"}
// after
Config.OIDCClientAssertion = &structs.OIDCClientAssertion{
  ClientID:  "nomad",
  KeySource: "pem",
  KeyFile:   "/etc/nomad/idp-signing-key.pem",
  KeyID:     "key-2024-01",
}
Defensive patterns

Strategy: validation

Validate before calling

if ca := am.Config.OIDCClientAssertion; ca != nil {
	if ca.ClientID == "" || ca.KeySource == "" || (ca.KeyFile == "" && ca.KeyPEM == "") {
		return errors.New("client assertion needs ClientID, KeySource, and a key")
	}
	if err := ca.Validate(); err != nil {
		return err
	}
}

Try / catch

if err := am.Validate(minTTL, maxTTL); err != nil {
	if strings.Contains(err.Error(), "invalid client assertion config") {
		// inspect wrapped inner error for the exact assertion field
	}
	return err
}

Prevention

When it happens

Trigger: Upserting an OIDC auth method whose Config.OIDCClientAssertion fails Validate() — e.g. missing KeySource/KeyFile/KeyID or ClientID components of the assertion — while relying on private-key JWT client auth to the IdP.

Common situations: Enabling client assertion for IdPs that require it (e.g. Azure AD with cert-based client auth) but leaving the signing key path or key ID unset; rotating keys and removing the referenced key file from config.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/50e41f1e91313b4b. Report an issue: GitHub.