{"record":{"id":"09d0c7b23255f2af","repo":"hashicorp/nomad","slug":"variable-error-encrypt-w","errorCode":null,"errorMessage":"variable error: encrypt: %w","messagePattern":"variable error: encrypt: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/variables_endpoint.go","lineNumber":115,"sourceCode":"\t}\n\terr = hasOperationPermissions(aclObj, args.Var.Namespace, args.Var.Path, args.Op)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = canonicalizeAndValidate(args)\n\tif err != nil {\n\t\treturn structs.NewErrRPCCoded(http.StatusBadRequest, err.Error())\n\t}\n\n\tvar ev *structs.VariableEncrypted\n\n\tswitch args.Op {\n\tcase structs.VarOpSet, structs.VarOpCAS, structs.VarOpLockAcquire,\n\t\tstructs.VarOpLockRelease:\n\t\tev, err = sv.encrypt(args.Var)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"variable error: encrypt: %w\", err)\n\t\t}\n\t\tnow := time.Now().UnixNano()\n\t\tev.CreateTime = now // existing will override if it exists\n\t\tev.ModifyTime = now\n\n\tcase structs.VarOpDelete, structs.VarOpDeleteCAS:\n\t\tev = &structs.VariableEncrypted{\n\t\t\tVariableMetadata: structs.VariableMetadata{\n\t\t\t\tNamespace:   args.Var.Namespace,\n\t\t\t\tPath:        args.Var.Path,\n\t\t\t\tModifyIndex: args.Var.ModifyIndex,\n\t\t\t},\n\t\t}\n\t}\n\n\t// Make a SVEArgs\n\tsveArgs := structs.VarApplyStateRequest{\n\t\tOp:           args.Op,","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/variables_endpoint.go#L97-L133","documentation":"For set/CAS/lock-acquire/lock-release operations, Apply encrypts the variable via sv.encrypt, which uses the cluster keyring. If encryption fails (keyring absent, no key material, keyring service error), the error is wrapped as 'variable error: encrypt: %w'. This indicates a keyring/encryption subsystem problem rather than a bad request.","triggerScenarios":"Calling Variables Apply with VarOpSet/VarOpCAS/VarOpLockAcquire/VarOpLockRelease when the keyring is not initialized or unreachable — e.g. keyring lost after restoring an old Raft state, or the version gate was bypassed.","commonSituations":"Cluster restored from backup without keyring metadata; keyring encryption keys revoked/rotated incorrectly; mixed-version clusters partially supporting keyrings; operator deleted keyring keys.","solutions":["Check server logs for the underlying keyring error from the encrypt call","Ensure the keyring is initialized (`nomad operator keyring` / keyring API) on all servers","Restore/rotate keyring keys if keys were lost or removed","Verify all servers meet the minimum keyring version (see related version gate)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// probe keyring availability before writing\n_, err := client.Agent().MakeHTTPClient().Get(\"/v1/operator/keyring/keys\")\n// non-200/absent keyring -> surface a clear error before Apply","typeGuard":null,"tryCatchPattern":"_, err := client.Variables().Apply(req, nil)\nif err != nil && strings.Contains(err.Error(), \"variable error: encrypt\") {\n    // inspect root cause via errors.Unwrap; check keyring state; do not blind-retry\n}","preventionTips":["Initialize and back up keyring keys before using variables","Never restore Raft state without its keyring metadata","Monitor keyring/rotation operations for failures","Keep all servers at keyring-capable versions"],"tags":["nomad","variables","encryption","keyring"],"backgroundTag":"keyring-encryption-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"}