hashicorp/nomad · error

failed to get active nomad key: %w

Error message

failed to get active nomad key: %w

What it means

Thrown by oidcClientAssertion when a.srv.encrypter.GetActiveKey() fails to return Nomad's active encryption key and key ID. The key is fetched to build the private_key_jwt client assertion when the auth method's client assertion KeySource is 'nomad'.

Source

Thrown at nomad/acl_endpoint.go:3167

	req, err := capOIDC.NewRequest(
		aclOIDCAuthURLRequestExpiryTime,
		redirect,
		opts...,
	)
	if err != nil {
		return nil, fmt.Errorf("failed to create OIDC request: %v", err)
	}

	return req, nil
}

func (a *ACL) oidcClientAssertion(config *structs.ACLAuthMethodConfig) (*cass.JWT, error) {
	// this nomad key will only actually be used if the client assertion config
	// KeySource = "nomad", but we get it here to avoid exposing more of the
	// codebase to the encrypter.
	nomadKey, nomadKID, err := a.srv.encrypter.GetActiveKey()
	if err != nil {
		return nil, fmt.Errorf("failed to get active nomad key: %w", err)
	}
	j, err := oidc.BuildClientAssertionJWT(config, nomadKey, nomadKID)
	if err != nil {
		return nil, fmt.Errorf("failed to build client_assertion jwt: %w", err)
	}
	if config.VerboseLogging {
		// a user initially setting up the auth method, as one might with
		// VerboseLogging enabled, may benefit from not having to do a full
		// login flow to see the jwt (and any possible Serialize() error).
		// we say "example" in the log, because the cap library will run
		// Serialize() again internally, so it won't use this same jwt.
		token, err := j.Serialize()
		if err != nil {
			return nil, fmt.Errorf("failed to serialize client_assertion jwt: %w", err)
		}
		a.logger.Debug("example client_assertion", "oidc_client_id", config.OIDCClientID, "jwt", token)
	}
	return j, nil

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check the wrapped cause and nomad server logs for keyring/encrypter initialization errors.
  2. On Nomad Enterprise, ensure the keyring is installed: nomad keyring list / rotate, and that the region has replicated keys.
  3. Restart the server agent so the encrypter re-initializes; verify raft keyring entries are healthy.
  4. Confirm KeySource is intentionally 'nomad' in OIDCClientAssertion; otherwise fix the auth method config.

Example fix

// before: client assertion pointing at nomad key on a cluster without keyring
"OIDCClientAssertion": { "KeySource": "nomad" }
// after: either install/verify the keyring or supply a static private key
nomad keyring list
"OIDCClientAssertion": { "KeySource": "nomad" } // run on Enterprise with keyring initialized
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: confirm keyring is initialized (Nomad Enterprise)
out, err := exec.Command("nomad", "keyring", "list").Output()
if err != nil || strings.Contains(string(out), "No keys") {
  return errors.New("nomad keyring not initialized")
}

Try / catch

key, kid, err := a.srv.encrypter.GetActiveKey()
if err != nil {
    return nil, fmt.Errorf("failed to get active nomad key: %w", err)
}

Prevention

When it happens

Trigger: Called from oidcRequest (during GetAuthMethod/OIDCAuthURL flows) or UpsertAuthMethods; the server's keyring encrypter is unavailable or not initialized — e.g. keyring not yet installed, key replication pending in a new region, or enterprise keyring corruption.

Common situations: Freshly-bootstrapped cluster before the initial keyring is created (Nomad Enterprise), a non-enterprise binary/config path where the encrypter is not wired, region replication lag, or keyring restore from backup failing.

Related errors


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