{"record":{"id":"5436ecc166addde0","repo":"getsops/sops","slug":"failed-to-encrypt-sops-data-key-to-vault-transit-b","errorCode":null,"errorMessage":"failed to encrypt sops data key to Vault transit backend '%s': %w","messagePattern":"failed to encrypt sops data key to Vault transit backend '(.+?)': %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hcvault/keysource.go","lineNumber":240,"sourceCode":"func (key *MasterKey) Encrypt(dataKey []byte) error {\n\treturn key.EncryptContext(context.Background(), dataKey)\n}\n\n// EncryptContext takes a SOPS data key, encrypts it with Vault Transit, and stores\n// the result in the EncryptedKey field.\nfunc (key *MasterKey) EncryptContext(ctx context.Context, dataKey []byte) error {\n\tfullPath := key.encryptPath()\n\n\tclient, err := vaultClient(key.VaultAddress, key.token, key.httpClient)\n\tif err != nil {\n\t\tlog.WithField(\"Path\", fullPath).Info(\"Encryption failed\")\n\t\treturn err\n\t}\n\n\tsecret, err := client.Logical().WriteWithContext(ctx, fullPath, encryptPayload(dataKey))\n\tif err != nil {\n\t\tlog.WithField(\"Path\", fullPath).Info(\"Encryption failed\")\n\t\treturn fmt.Errorf(\"failed to encrypt sops data key to Vault transit backend '%s': %w\", fullPath, err)\n\t}\n\tencryptedKey, err := encryptedKeyFromSecret(secret)\n\tif err != nil {\n\t\tlog.WithField(\"Path\", fullPath).Info(\"Encryption failed\")\n\t\treturn fmt.Errorf(\"failed to encrypt sops data key to Vault transit backend '%s': %w\", fullPath, err)\n\t}\n\n\tkey.EncryptedKey = encryptedKey\n\tlog.WithField(\"Path\", fullPath).Info(\"Encryption successful\")\n\treturn nil\n}\n\n// EncryptIfNeeded encrypts the provided SOPS data key, if it has not been\n// encrypted yet.\nfunc (key *MasterKey) EncryptIfNeeded(dataKey []byte) error {\n\tif key.EncryptedKey == \"\" {\n\t\treturn key.Encrypt(dataKey)\n\t}","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/hcvault/keysource.go#L222-L258","documentation":"This error wraps any failure returned by the Vault API when SOPS writes the data key to the transit encrypt endpoint (`<enginePath>/encrypt/<keyName>`) during MasterKey.EncryptContext. It means the Vault server itself rejected or could not complete the transit encrypt request (auth, permissions, key existence, connectivity). SOPS wraps the underlying client error so the failing transit path is included.","triggerScenarios":"client.Logical().WriteWithContext(ctx, fullPath, encryptPayload(dataKey)) returns a non-nil error in EncryptContext — e.g. HTTP 403 from missing/invalid token, 404 for unknown key name or engine path, 400 invalid request, or network/TLS failure reaching the Vault address.","commonSituations":"VAULT_TOKEN expired or ~/.vault-token stale; token lacks `update` capability on transit/encrypt/<keyName>; typo'd KeyName or EnginePath in the sops creation rule (hc_vault:// URI); transit engine not mounted at the given path; Vault behind a proxy/DNS that is unreachable; Vault sealed.","solutions":["Run `vault status` and `vault token lookup` to confirm the server is reachable and the token is valid.","Verify the key exists: `vault read <enginePath>/keys/<KeyName>`; create it with `vault write -f <enginePath>/keys/<KeyName>` if missing.","Check token policy grants `update` on `<enginePath>/encrypt/*` (`vault policy read`).","Confirm the hc_vault URI path parses to the intended engine path and key name (format https://vault:8200/v1/<engine>/keys/<keyName>).","Check network/TLS: curl the Vault health endpoint; ensure VAULT_ADDR/VAULT_CACERT are consistent.","If Vault is sealed, unseal it: `vault operator unseal`."],"exampleFix":"// before: sops config with wrong key name\nhc_vault: https://vault.example.com/v1/transit/keys/prod-key\n// after: key name matching what exists in Vault (created via `vault write -f transit/keys/sops`)\nhc_vault: https://vault.example.com/v1/transit/keys/sops","handlingStrategy":"try-catch","validationCode":"// Go: verify reachability and auth before encrypting\nfunc checkVault(addr, token string) error {\n\tcfg := api.DefaultConfig()\n\tcfg.Address = addr\n\tclient, err := api.NewClient(cfg)\n\tif err != nil { return err }\n\tif token != \"\" { client.SetToken(token) }\n\tif _, err := client.Sys().Health(); err != nil { return err }\n\t_, err = client.Auth().Token().LookupSelf()\n\treturn err\n}","typeGuard":null,"tryCatchPattern":"if err := key.EncryptContext(ctx, dataKey); err != nil {\n\tvar ve *api.ResponseError\n\tif errors.As(err, &ve) {\n\t\tlog.Printf(\"vault %d on %s: %s\", ve.StatusCode, fullPath, ve.Errors)\n\t}\n\treturn fmt.Errorf(\"vault encrypt failed (check token/policy/key existence): %w\", err)\n}","preventionTips":["Run `vault token lookup` in CI before sops encrypt/decrypt to catch expired tokens.","Pin the hc_vault URI (address + engine path + key name) and validate the key exists with `vault read transit/keys/<name>`.","Grant the token only the transit encrypt/decrypt update capabilities it needs.","Set VAULT_ADDR/VAULT_CACERT consistently with the URI scheme to avoid TLS mismatches.","Alert on Vault sealed status so operators unseal before sops jobs run."],"tags":["vault","transit","encryption","network","authentication"],"backgroundTag":"vault-transit-encrypt-failed","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}