hashicorp/nomad · warning

keyring has not been initialized yet

Error message

keyring has not been initialized yet

What it means

activeCipherSet resolves the currently active root key from the FSM state, then waits for the corresponding cipherSet. If state has no active root key at all (GetActiveRootKey returns nil), the keyring was never initialized and the error "keyring has not been initialized yet" is returned to callers like Encrypt, SignClaims, and GetActiveKey.

Source

Thrown at nomad/encrypter.go:764

	}

	return ks.rootKey, nil
}

// activeCipherSetLocked returns the cipherSet that belongs to the key marked as
// active in the state store (so that it's consistent with raft).
//
// If a key is rotated immediately following a leader election, plans that are
// in-flight may get signed before the new leader has decrypted the key. Allow
// for a short timeout-and-retry to avoid rejecting plans
func (e *Encrypter) activeCipherSet() (*cipherSet, error) {
	store := e.srv.fsm.State()
	key, err := store.GetActiveRootKey(nil)
	if err != nil {
		return nil, err
	}
	if key == nil {
		return nil, fmt.Errorf("keyring has not been initialized yet")
	}

	ctx, cancel := context.WithTimeout(e.srv.shutdownCtx, time.Second)
	defer cancel()
	return e.waitForKey(ctx, key.KeyID)
}

// cipherSetByIDLocked returns the cipherSet for the specified keyID. The
// caller must read-lock the keyring
func (e *Encrypter) cipherSetByIDLocked(keyID string) (*cipherSet, error) {
	cipherSet, ok := e.keyring[keyID]
	if !ok {
		return nil, fmt.Errorf("no such key %q in keyring", keyID)
	}
	return cipherSet, nil
}

// RemoveKey removes a key by ID from the keyring

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Wait/retry: on a healthy cluster the leader initializes the keyring automatically shortly after startup
  2. Verify an active root key exists (keyring list / GetActiveRootKey); if none, run a keyring bootstrap/rotate via the keyring API
  3. Restore keyring state if a snapshot restore dropped root keys
  4. Check leader election — keyring init is leader-driven; ensure a stable leader exists

Example fix

// before: sign immediately on fresh agent
claims, err := encrypter.SignClaims(wid)
// after: wait until keyring is initialized
err := waitForCondition(func() bool { _, err := store.GetActiveRootKey(nil); return err == nil })
claims, err := encrypter.SignClaims(wid)
Defensive patterns

Strategy: retry

Validate before calling

store := srv.fsm.State()
key, err := store.GetActiveRootKey(nil)
if key == nil { /* keyring not initialized; wait or bootstrap before encrypt/sign */ }

Type guard

func keyringReady(s *state.Store) bool { k, _ := s.GetActiveRootKey(nil); return k != nil }

Try / catch

if err != nil && err.Error() == "keyring has not been initialized yet" {
    // backoff and retry until leader completes keyring init, or run keyring bootstrap
}

Prevention

When it happens

Trigger: Any encryption/signing call made before the keyring bootstrap (initial keyring rotation) completed, or on a server whose state store lacks an active root key — e.g. a brand-new cluster or one restored without keyring data.

Common situations: Calling workload-identity-dependent features immediately after cluster creation before the automatic keyring init finishes; restoring a state snapshot that omitted root keys; elections/state wipe leaving the FSM empty.

Related errors


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