{"record":{"id":"7660abdd0449bdfd","repo":"hashicorp/nomad","slug":"no-such-key","errorCode":null,"errorMessage":"no such key","messagePattern":"no such key","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/encrypter.go","lineNumber":721,"sourceCode":"func (e *Encrypter) waitForKey(ctx context.Context, keyID string) (*cipherSet, error) {\n\tvar ks *cipherSet\n\n\terr := helper.WithBackoffFunc(ctx, 50*time.Millisecond, 100*time.Millisecond,\n\t\tfunc() error {\n\t\t\te.keyringLock.RLock()\n\t\t\tdefer e.keyringLock.RUnlock()\n\t\t\tvar err error\n\t\t\tks, err = e.cipherSetByIDLocked(keyID)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif ks == nil {\n\t\treturn nil, fmt.Errorf(\"no such key\")\n\t}\n\treturn ks, nil\n}\n\n// GetActiveKey returns the active private key and its kid (key id)\nfunc (e *Encrypter) GetActiveKey() (*rsa.PrivateKey, string, error) {\n\tc, err := e.activeCipherSet()\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\treturn c.rsaPrivateKey, c.rootKey.Meta.KeyID, nil\n}\n\n// GetKey retrieves the key material by ID from the keyring.\nfunc (e *Encrypter) GetKey(keyID string) (*structs.UnwrappedRootKey, error) {\n\te.keyringLock.Lock()\n\tdefer e.keyringLock.Unlock()\n","sourceCodeStart":703,"sourceCodeEnd":739,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/encrypter.go#L703-L739","documentation":"waitForKey polls the in-memory keyring for a cipherSet matching a key ID within the caller-provided context deadline. If the timeout expires or the key is never found, it returns \"no such key\". This means the key exists in state but the local agent's Encrypter never loaded it (or hasn't yet).","triggerScenarios":"Decrypt/activeCipherSet/waitForPublicKey called with a KeyID whose cipherSet is absent after the wait deadline — keyring replication lag, the agent failed to load that key (see errors 2200-2206), or the key ID is wrong.","commonSituations":"Workload signed with a key from before an agent joined/replicated; key decryption failures at load time on this agent; using a stale/incorrect key ID after rotation.","solutions":["Confirm the key ID via the keyring list API and check agent logs for addCipher/decrypt failures for that key","Wait for keyring replication or retry shortly after key rotation","Fix the underlying key-loading failure (KMS auth, bad key material) so the cipherSet gets added","Verify you're querying an agent/scheduler that is part of the same region/authority as the key"],"exampleFix":"// before: decrypt immediately after rotate with new key id on a lagging agent\n// after: retry/poll until the keyring list shows the key on all agents, or use the active key id\nks, err := e.activeCipherSet() // use currently active key instead of unknown key id","handlingStrategy":"retry","validationCode":"// poll keyring list until the desired KeyID appears before calling decrypt\nfor i := 0; i < 10; i++ {\n    if keyringHas(kid) { break } ; time.Sleep(500 * time.Millisecond)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && err.Error() == \"no such key\" {\n    // retry after replication delay, or fall back to the active key\n}","preventionTips":["After key rotation, wait for keyring replication across servers before using the new KeyID","Check agent logs for key-load failures on every startup","Reference the active key ID rather than cached stale IDs"],"tags":["keyring","key-not-found","timeout"],"backgroundTag":"key-not-found","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}