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 be

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. 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.
  2. If the provider only supports x5t/SHA-1, disable FIPS-140 mode or use a different provider/key-id mechanism.
  3. 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

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

Related errors


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