hashicorp/nomad · error · ErrInvalidKeyIDHeader
%w; certificate-derived key header must be one of: %q, %q
Error message
%w; certificate-derived key header must be one of: %q, %q
What it means
When the OIDC client assertion is certificate-derived (pem_cert or pem_cert_file set), the KeyIDHeader must be either x5t (SHA-1 cert thumbprint) or x5tS256 (SHA-256 thumbprint). Any other header fails with ErrInvalidKeyIDHeader. Additionally, x5t is rejected outright when FIPS-140 mode is enabled because SHA-1 is forbidden.
Source
Thrown at nomad/structs/acl.go:1897
if k.KeyID != "" && (k.PemCert != "" || k.PemCertFile != "") {
return ErrAmbiguousClientAssertionKeyID
}
if k.PemCertFile != "" {
if !path.IsAbs(k.PemCertFile) {
return fmt.Errorf("%w: must be absolute; got: %s", ErrInvalidClientAssertionCertPath, k.PemCertFile)
}
}
// only allow certain key id headers
// only "kid" for KeyID
if k.KeyID != "" && k.KeyIDHeader != OIDCClientAssertionHeaderKid {
return fmt.Errorf("%w; key header for key ID must be %q",
ErrInvalidKeyIDHeader, OIDCClientAssertionHeaderKid)
}
// only "x5t*" for certs
if k.PemCert != "" || k.PemCertFile != "" {
if k.KeyIDHeader != OIDCClientAssertionHeaderX5t && k.KeyIDHeader != OIDCClientAssertionHeaderX5tS256 {
return fmt.Errorf("%w; certificate-derived key header must be one of: %q, %q",
ErrInvalidKeyIDHeader, OIDCClientAssertionHeaderX5tS256, OIDCClientAssertionHeaderX5t)
}
if fips140.Enabled() && k.KeyIDHeader == OIDCClientAssertionHeaderX5t {
return errors.New("x5t assertion headers use SHA-1, which is forbidden in FIPS-140 mode")
}
}
return nil
}
// ACLAuthClaims is the claim mapping of the OIDC auth method in a format that
// can be used with go-bexpr. This structure is used during rule binding
// evaluation.
type ACLAuthClaims struct {
Value map[string]string `bexpr:"value"`
List map[string][]string `bexpr:"list"`
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Set key_id_header to "x5tS256" (preferred) or "x5t" for certificate-derived assertions.
- If in FIPS-140 mode, use x5tS256 and ensure your IdP accepts SHA-256 thumbprints.
- Verify the exact header constant spelling ("x5tS256", not "x5t256").
Example fix
// before pem_cert_file = "/etc/ssl/client.crt" key_id_header = "kid" // after pem_cert_file = "/etc/ssl/client.crt" key_id_header = "x5tS256"
Defensive patterns
Strategy: validation
Validate before calling
if (k.PemCert != "" || k.PemCertFile != "") {
switch k.KeyIDHeader {
case "x5t", "x5tS256":
default:
return fmt.Errorf("cert-based assertion needs x5t or x5tS256 header, got %q", k.KeyIDHeader)
}
if fipsEnabled && k.KeyIDHeader == "x5t" {
return errors.New("x5t forbidden in FIPS mode; use x5tS256")
}
} Prevention
- Prefer x5tS256 everywhere to stay FIPS-compliant.
- Confirm your IdP supports SHA-256 thumbprints (x5tS256).
- Check the exact header constant spelling.
When it happens
Trigger: Setting key_id_header to "kid" (or anything else) while pem_cert/pem_cert_file are configured; or using "x5t" on a Nomad server running with FIPS-140 mode enabled.
Common situations: Swapping a key_id config to cert-based without updating the header; Azure AD setups needing x5t while the Nomad server is in FIPS mode; typo like "x5t256" instead of "x5tS256".
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- invalid config: %w
- %w; key header for key ID must be %q
- missing OIDCDiscoveryURL
- missing OIDCClientID
- JWT auth method requires either OIDCDiscoveryURL, or JWKS UR
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/4908b835aaea820b.
Report an issue: GitHub.