{"record":{"id":"3d965da49e595996","repo":"hashicorp/nomad","slug":"could-not-add-cipher-w","errorCode":null,"errorMessage":"could not add cipher: %w","messagePattern":"could not add cipher: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/encrypter.go","lineNumber":617,"sourceCode":"\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\trootKey := &structs.UnwrappedRootKey{\n\t\tMeta:   meta,\n\t\tKey:    key,\n\t\tRSAKey: rsaKey,\n\t}\n\n\tvar generatedCipher *cipherSet\n\n\terr = helper.WithBackoffFunc(ctx, minBackoff, maxBackoff, func() error {\n\t\tgeneratedCipher, err = e.generateCipher(rootKey)\n\t\tif err != nil {\n\t\t\terr := fmt.Errorf(\"could not add cipher: %w\", err)\n\t\t\te.log.Error(err.Error(), \"key_id\", meta.KeyID)\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Send the cipher to the response channel or exit if the context is\n\t// canceled.\n\t//\n\t// The context is canceled when the server is shutting down or when another\n\t// task decrypting the same key completes.\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase respCh <- generatedCipher:","sourceCodeStart":599,"sourceCodeEnd":635,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/encrypter.go#L599-L635","documentation":"After the DEK was decrypted, Encrypter.generateCipher failed while building the cipherSet from the root key, and the failure is wrapped as \"could not add cipher\". This error is retried with backoff before being returned from addCipher.","triggerScenarios":"e.generateCipher(rootKey) returns an error — missing rootKey.Meta, unsupported algorithm, aead wrapper configuration failure, or RSA key parse failure (errors 2203-2206).","commonSituations":"A root key in state has corrupted or incomplete fields (nil Meta, zeroed Key, malformed RSAKey); upgrading from a version writing a different key format; a bug in state restoration producing partial UnwrappedRootKey values.","solutions":["Unwrap the inner error to see which generateCipher step failed and follow that specific fix","Validate the root key record in state (Meta, Algorithm, Key, RSAKey lengths) via keyring inspection endpoints","Rotate the affected key to regenerate a well-formed root key record","Upgrade/verify Nomad version consistency across agents if the key format changed between versions"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// preflight: ensure the root key record is complete\nif rootKey == nil || rootKey.Meta == nil || len(rootKey.Key) != 32 { /* reject before addCipher */ }","typeGuard":"func validRootKey(k *structs.UnwrappedRootKey) bool { return k != nil && k.Meta != nil && k.Meta.KeyID != \"\" && len(k.Key) == 32 }","tryCatchPattern":"if err != nil {\n    if strings.HasPrefix(err.Error(), \"could not add cipher:\") {\n        // unwrap cause and fix key material, then retry rotation\n    }\n}","preventionTips":["Only create/rotate keys through the official keyring API","Validate snapshots after restore by listing keyring keys","Keep Nomad versions homogeneous across servers"],"tags":["encryption","keyring","cipher-setup"],"backgroundTag":"cipher-configuration-failed","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"}