hashicorp/nomad · error
no such key %q in keyring
Error message
no such key %q in keyring
What it means
cipherSetByIDLocked looks up a keyring entry (a cipherSet holding the decrypted root key and related keys) by keyID in the Encrypter's in-memory keyring map. When no entry exists for the requested keyID, it returns "no such key %q in keyring". This means the key was never added, has been removed, or the caller is using a key ID the server does not know about.
Source
Thrown at nomad/encrypter.go:777
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
func (e *Encrypter) RemoveKey(keyID string) error {
e.keyringLock.Lock()
defer e.keyringLock.Unlock()
delete(e.keyring, keyID)
return nil
}
// wrapRootKey encrypts the key for every KEK provider and returns a RootKey
// with wrapped keys. On legacy clusters, this also serializes the wrapped key
// to the on-disk keystore.
func (e *Encrypter) wrapRootKey(rootKey *structs.UnwrappedRootKey, isUpgraded bool) (*structs.RootKey, error) {
wrappedKeys := structs.NewRootKey(rootKey.Meta)View on GitHub (pinned to 482b49bf1a)
Solutions
- Verify the keyID passed to GetKey/GetPublicKey/AddWrappedKey matches an existing key (list keyring metadata via the API or state store).
- If the key was removed intentionally, re-add it with AddWrappedKey or create a new key via the keyring API.
- Check that the server has fully restored its keyring on startup (look for earlier keyring restore errors in the logs).
- Confirm you are querying the correct cluster/region that holds the key.
Example fix
// before
key, err := encrypter.GetKey("my-key-id")
// after
if !encrypter.HasKey("my-key-id") { // guard or list keys first
return fmt.Errorf("key %q not configured in keyring", "my-key-id")
}
key, err := encrypter.GetKey("my-key-id") Defensive patterns
Strategy: validation
Validate before calling
if _, err := encrypter.GetKey(keyID); err != nil {
// treat as missing key; list keyring metadata or create the key first
return fmt.Errorf("key %q unavailable before use: %w", keyID, err)
} Try / catch
key, err := encrypter.GetKey(keyID)
if err != nil && strings.Contains(err.Error(), "no such key") {
// handle missing key: create/rotate or fail fast with a clear message
} Prevention
- Always resolve key IDs from the keyring metadata API rather than hardcoding them.
- Check server startup logs for keyring restore completion before issuing key lookups.
- Track key removals (RemoveKey) and update all consumers of the key ID.
When it happens
Trigger: Calling Encrypter.GetKey, GetPublicKey, or AddWrappedKey with a keyID that is not present in e.keyring; after RemoveKey deleted the key; or before the key has been loaded/restored from the keyring store on server startup.
Common situations: Querying a key by a mistyped or stale key ID; a workload references a key that was rotated out and removed; a server that has not finished restoring keys from the state store receives a key request; multiple clusters/regions where the key only exists elsewhere.
Related errors
- unable to decrypt wrapped key
- root key not found
- root key in use, cannot delete
- failed to configure keyring: %v
- error parsing 'keyring': %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/acaed543a3ddc482.
Report an issue: GitHub.