hashicorp/nomad · error
invalid PrivateKey: %w
Error message
invalid PrivateKey: %w
What it means
Wraps the validation failure of the OIDCClientAssertion PrivateKey sub-object when the auth client assertion KeySource is `private_key`. The nested PrivateKey.Validate() failed (missing key/cert material or unreadable content), and Nomad re-raises it with the `invalid PrivateKey:` prefix. It means the configured private key for OIDC client authentication is invalid.
Source
Thrown at nomad/structs/acl.go:1781
func (c *OIDCClientAssertion) IsSet() bool {
return c != nil && c.KeySource != ""
}
func (c *OIDCClientAssertion) Validate() error {
if c == nil {
return nil
}
if len(c.Audience) == 0 || c.Audience[0] == "" {
return errors.New("missing Audience")
}
switch c.KeySource {
case OIDCKeySourceNomad:
case OIDCKeySourcePrivateKey:
if c.PrivateKey == nil {
return errors.New("PrivateKey is required for `private_key` KeySource")
}
if err := c.PrivateKey.Validate(); err != nil {
return fmt.Errorf("invalid PrivateKey: %w", err)
}
case OIDCKeySourceClientSecret:
if c.ClientSecret == "" {
return errors.New("OIDCClientSecret is required for `client_secret` KeySource")
}
default:
return fmt.Errorf("invalid KeySource %q", c.KeySource)
}
return nil
}
type OIDCClientAssertionKeyIDHeader string
const (
OIDCClientAssertionHeaderKid OIDCClientAssertionKeyIDHeader = "kid"
OIDCClientAssertionHeaderX5t OIDCClientAssertionKeyIDHeader = "x5t"
OIDCClientAssertionHeaderX5tS256 OIDCClientAssertionKeyIDHeader = "x5t#S256"
)View on GitHub (pinned to 482b49bf1a)
Solutions
- Read the wrapped %w message to see which nested field failed, then supply exactly one valid private key (PemKey or PemKeyFile).
- Ensure the PEM block is complete including -----BEGIN/END----- lines.
- Verify the referenced file exists and is readable by the Nomad server.
- Run the provider validation again after fixing.
Example fix
// before key_source = "private_key" pem_key = "" pem_key_file = "/etc/ssl/client.key" pem_cert_file = "/etc/ssl/client.crt" // after key_source = "private_key" pem_key_file = "/etc/ssl/client.key" // complete, valid PEM only
Defensive patterns
Strategy: validation
Validate before calling
func checkPrivateKey(k *OIDCClientAssertionPrivateKey) error {
if k == nil || (k.PemKey == "" && k.PemKeyFile == "") {
return errors.New("private key material required")
}
if k.PemKey != "" && k.PemKeyFile != "" {
return errors.New("set only one of pem_key or pem_key_file")
}
if k.PemKey != "" && !strings.Contains(k.PemKey, "-----BEGIN") {
return errors.New("pem_key is not a valid PEM block")
}
return nil
} Type guard
func hasValidPEM(s string) bool {
return strings.Contains(s, "-----BEGIN") && strings.Contains(s, "-----END")
} Try / catch
if err := client.ACLAuthMethods().Upsert(...); err != nil {
var wrapped interface{ Unwrap() error }
if errors.As(err, &target) && strings.Contains(err.Error(), "invalid PrivateKey") {
// surface nested PrivateKey validation detail to operator
}
} Prevention
- Provide exactly one of pem_key or pem_key_file.
- Verify PEM files load with openssl before configuring.
- Check file readability by the Nomad server user.
When it happens
Trigger: Validating an OIDC provider/auth-method whose OIDCClientAssertion has KeySource set to "private_key" but whose PrivateKey fails Validate() - e.g. nil/empty PemKey and PemKeyFile, both set simultaneously, or malformed PEM data.
Common situations: Paste of PEM content with missing header/footer lines; specifying both pem_key and pem_key_file; uploading a truncated key; referencing a key file path that was emptied by templating.
Related errors
- missing OIDCDiscoveryURL
- missing OIDCClientID
- missing auth method name
- missing client nonce
- missing redirect URI
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/81478f67f07b9e41.
Report an issue: GitHub.