hashicorp/nomad · error

OIDCClientSecret is required for `client_secret` KeySource

Error message

OIDCClientSecret is required for `client_secret` KeySource

What it means

Returned by OIDCClientAssertion.Validate when KeySource is client_secret but ClientSecret is empty. That key source signs client assertions with the secret, so a missing secret makes the assertion configuration unusable.

Source

Thrown at nomad/structs/acl.go:1785

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"
)

// OIDCClientAssertionKey contains key material provided by users for Nomad
// to use to sign the private key JWT.
// See api.OIDCClientAssertionKey for full field descriptions.

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set OIDCClientAssertion.ClientSecret to the secret from the IdP client registration
  2. Load the secret from a secure source (Vault, env) at deploy time and verify it is non-empty
  3. Choose a different KeySource if no client secret exists

Example fix

// before
assertion := &api.OIDCClientAssertion{KeySource: "client_secret", Audience: aud, ClientSecret: ""}
// after
assertion := &api.OIDCClientAssertion{KeySource: "client_secret", Audience: aud, ClientSecret: os.Getenv("OIDC_CLIENT_SECRET")}
Defensive patterns

Strategy: validation

Validate before calling

func clientSecretAssertionOK(c *structs.OIDCClientAssertion) bool {
  return c == nil || c.KeySource != structs.OIDCKeySourceClientSecret || c.ClientSecret != ""
}

Prevention

When it happens

Trigger: Configuring OIDCClientAssertion with KeySource "client_secret" while ClientSecret is empty, then upserting the auth method.

Common situations: Secrets left to a template variable that rendered empty; teams switching from nomad/private_key key sources and not yet obtaining the IdP client secret; redaction tooling that blanked the secret before submission.

Related errors


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