hashicorp/nomad · error
x5t assertion headers use SHA-1, which is forbidden in FIPS-
Error message
x5t assertion headers use SHA-1, which is forbidden in FIPS-140 mode
What it means
hashKeyID computes the x5t (SHA-1 thumbprint, per RFC 7515 §4.1.7) or x5t#S256 header used by the OIDC provider to locate the certificate that verifies the private-key JWT. In FIPS-140 mode SHA-1 is disallowed, so selecting the x5t header kind fails immediately.
Source
Thrown at lib/auth/oidc/client_assertion.go:197
if err != nil {
return nil, fmt.Errorf("failed to parse %s bytes: %w", source, err)
}
now := time.Now()
if now.Before(cert.NotBefore) || now.After(cert.NotAfter) {
return nil, errors.New("certificate has expired or is not yet valid")
}
return cert, nil
}
// hashKeyID derives a "certificate thumbprint" that the OIDC provider uses
// to find the certificate to verify the private key JWT signature.
// https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.7
func hashKeyID(cert *x509.Certificate, header structs.OIDCClientAssertionKeyIDHeader) (string, error) {
var hasher hash.Hash
switch header {
case structs.OIDCClientAssertionHeaderX5t:
if fips140.Enabled() {
return "", errors.New("x5t assertion headers use SHA-1, which is forbidden in FIPS-140 mode")
}
hasher = sha1.New()
case structs.OIDCClientAssertionHeaderX5tS256:
hasher = sha256.New()
default:
// this should be validated long before here, at upsert
return "", fmt.Errorf(`%w; must be one of: "x5t", "x5t#S256"`, structs.ErrInvalidKeyIDHeader)
}
hasher.Write(cert.Raw)
hashed := hasher.Sum(nil)
return base64.RawURLEncoding.EncodeToString(hashed), nil
}
// newlineHeaders allows flexible copy-paste of a one-line key/cert PEM
// by adding newlines around "----BEGIN.*-----" and
// "-----END.*(KEY|CERTIFICATE)-----"
// it's okay to have extra whitespace, but it's imperative that there beView on GitHub (pinned to 482b49bf1a)
Solutions
- Switch the auth method's client-assertion key ID header to structs.OIDCClientAssertionHeaderX5tS256 (SHA-256), which is FIPS-allowed — verify your OIDC provider supports x5t#S256.
- If the provider only supports x5t/SHA-1, disable FIPS-140 mode or use a different provider/key-id mechanism.
- Confirm with the provider documentation which x5c thumbprint header it validates before changing config.
Example fix
// before header = structs.OIDCClientAssertionHeaderX5t // after header = structs.OIDCClientAssertionHeaderX5tS256
Defensive patterns
Strategy: validation
Validate before calling
if fips140.Enabled() && header == structs.OIDCClientAssertionHeaderX5t {
return errors.New("FIPS mode requires x5t#S256 (SHA-256) key ID header")
} Prevention
- Default to x5t#S256 in all OIDC client-assertion configs
- Confirm provider support for x5t#S256 before enabling FIPS mode
- Document FIPS incompatibility of SHA-1 x5t in deployment runbooks
When it happens
Trigger: BuildClientAssertionJWT is called with key ID header structs.OIDCClientAssertionHeaderX5t while fips140.Enabled() is true (Nomad built/running with FIPS-140 mode enabled).
Common situations: Deployments in FIPS-compliant environments (government, regulated industries) whose OIDC auth method still specifies the legacy x5t header, which the OIDC provider only supports in SHA-1 form.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- %w; certificate-derived key header must be one of: %q, %q
- no auth method config or client assertion
- missing Audience
- PrivateKey is required for `private_key` KeySource
- invalid KeyIDHeader
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/af743cdc15560b0b.
Report an issue: GitHub.