hashicorp/nomad · error

unknown OIDC KeySource %q

Error message

unknown OIDC KeySource %q

What it means

BuildClientAssertionJWT builds a signed client-assertion JWT for OIDC login, and the OIDCClientAssertion's KeySource field holds a value the builder does not implement. The default branch is a defensive catch-all: KeySource must be one of the supported structs.OIDCClientAssertionKeySource values, and this value is not.

Source

Thrown at lib/auth/oidc/client_assertion.go:113

			)
		} else {
			// otherwise, derive it from the cert
			cert, err := getCassCert(as.PrivateKey)
			if err != nil {
				return nil, err
			}
			keyID, err := hashKeyID(cert, as.PrivateKey.KeyIDHeader)
			if err != nil {
				return nil, err
			}
			opts = append(opts, cass.WithHeaders(map[string]string{
				string(as.PrivateKey.KeyIDHeader): keyID,
			}))
		}
		return cass.NewJWTWithRSAKey(clientID, as.Audience, algo, rsaKey, opts...)

	default: // this shouldn't happen, but just in case
		return nil, fmt.Errorf("unknown OIDC KeySource %q", as.KeySource)
	}
}

// getCassPrivateKey parses the structs.OIDCClientAssertionKey PemKeyFile
// or PemKey, depending on which is set.
func getCassPrivateKey(k *structs.OIDCClientAssertionKey) (key *rsa.PrivateKey, err error) {
	var bts []byte
	var source string // for informative error messages

	// pem file on disk
	if k.PemKeyFile != "" {
		source = "PemKeyFile"
		bts, err = os.ReadFile(k.PemKeyFile)
		if err != nil {
			return nil, fmt.Errorf("error reading %s: %w", source, err)
		}
	}
	// or pem string

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set KeySource to a supported value (e.g. the private-key / private-key-file variants defined in structs) — check the exact accepted strings in structs.ACLAuthMethodConfig docs.
  2. Verify Nomad server version matches the config: a KeySource from a newer release needs an upgraded binary.
  3. Fix typos in the API/terraform payload before submitting the auth method.

Example fix

// before
assertion := &structs.OIDCClientAssertion{
  KeySource: "private_key_file",
}
// after: exact supported enum value
assertion := &structs.OIDCClientAssertion{
  KeySource: structs.OIDCClientAssertionKeySourcePrivateKeyFile,
}
Defensive patterns

Strategy: validation

Validate before calling

switch assertion.KeySource {
case structs.OIDCClientAssertionKeySourcePrivateKey,
     structs.OIDCClientAssertionKeySourcePrivateKeyFile:
  // ok
default:
  return fmt.Errorf("KeySource %q unsupported by this Nomad server", assertion.KeySource)
}

Type guard

func keySourceSupported(ks structs.OIDCClientAssertionKeySource) bool {
  switch ks {
  case structs.OIDCClientAssertionKeySourcePrivateKey,
       structs.OIDCClientAssertionKeySourcePrivateKeyFile:
    return true
  }
  return false
}

Try / catch

jwt, err := client.BuildClientAssertionJWT(ctx, assertion)
if err != nil && strings.Contains(err.Error(), "unknown OIDC KeySource") {
  return fmt.Errorf("fix KeySource in auth method config or upgrade Nomad: %w", err)
}

Prevention

When it happens

Trigger: oidcClientAssertion → BuildClientAssertionJWT during OIDC auth with client assertion configured, when the API payload contains an unrecognized/empty KeySource (e.g. a typo or a KeySource added in a newer Nomad than the running server).

Common situations: Terraform/Nomad API config with misspelled KeySource string; config written for a newer Nomad version running on an older binary; empty KeySource field in the auth method config.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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