hashicorp/nomad · error
could not encrypt: %w
Error message
could not encrypt: %w
What it means
The KMS wrapper's Encrypt call failed while encrypting data with the cipher set's root key. The underlying wrapper error (context canceled, KMS backend unavailable, invalid key state) is wrapped with 'could not encrypt'.
Source
Thrown at nomad/encrypter.go:282
}
return nil
}
// Encrypt encrypts the clear data with the cipher for the active root key, and
// returns the cipher text (including the nonce), and the key ID used to encrypt
// it
func (e *Encrypter) Encrypt(cleartext []byte) ([]byte, string, error) {
cs, err := e.activeCipherSet()
if err != nil {
return nil, "", err
}
keyID := cs.rootKey.Meta.KeyID
additional := kms.WithAad([]byte(keyID)) // include the keyID in the seal inputs
bi, err := cs.wrapper.Encrypt(e.srv.shutdownCtx, cleartext, additional)
if err != nil {
return nil, "", fmt.Errorf("could not encrypt: %w", err)
}
return bi.Ciphertext, keyID, nil
}
// Decrypt takes an encrypted buffer and then root key ID. It extracts
// the nonce, decrypts the content, and returns the cleartext data.
func (e *Encrypter) Decrypt(ciphertext []byte, keyID string) ([]byte, error) {
ctx, cancel := context.WithTimeout(e.srv.shutdownCtx, time.Second)
defer cancel()
ks, err := e.waitForKey(ctx, keyID)
if err != nil {
return nil, err
}
additional := kms.WithAad([]byte(keyID)) // keyID was included in the seal inputs
bi := &kms.BlobInfo{
Ciphertext: ciphertext, // nonce was stored alongside ciphertext
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Inspect the wrapped cause to identify the failing provider (local AEAD vs Vault transit vs cloud KMS)
- For remote KMS providers, verify credentials, network reachability, and IAM/key permissions
- Retry the operation if the server was mid-restart or the key was rotating
- If shutdownCtx was canceled, re-issue the request after the server is healthy
Example fix
// before: expired Vault token breaks transit encryption
// vault token renew or fix vault config token
// after: ensure the agent's Vault config uses a renewable token / approle
// vault {
// address = "https://vault:8200"
// role = "nomad-server"
// } Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check Vault transit reachability before encrypting
resp, err := http.Get("https://vault:8200/v1/sys/health")
if err != nil || resp.StatusCode >= 500 {
return fmt.Errorf("vault unreachable, encryption will fail")
} Try / catch
blob, keyID, err := encrypter.Encrypt(ctx, plaintext)
if err != nil {
var ctxErr error
if errors.Is(err, context.Canceled) || srvShutdownInProgress {
ctxErr = fmt.Errorf("server shutting down, requeue work: %w", err)
} else if isTransientKMS(err) {
ctxErr = fmt.Errorf("transient KMS error, retry with backoff: %w", err)
}
return nil, ctxErr
} Prevention
- Renew Vault tokens automatically (AppRole / token renewal) for transit provider
- Grant cloud KMS IAM permissions broadly enough for encrypt/decrypt on the key
- Monitor server shutdown windows and pause workloads during maintenance
- Add health checks against the KMS backend in deployment pipelines
When it happens
Trigger: Encrypter.Encrypt -> encrypt -> cs.wrapper.Encrypt(shutdownCtx, cleartext, aad) returns an error; with the AEAD provider this means local cipher setup failed, with transit/cloud KMS providers it means the remote call failed. Also surfaces if the server is shutting down (shutdownCtx canceled).
Common situations: Vault transit token expired, AWS/GCP/Azure KMS network or IAM error, server shutdown in progress, or internal AEAD failure after a keyring reload raced an encryption request.
Related errors
- unable to decrypt wrapped key
- no such KMS provider %q configured
- unable to create KMS wrapper for provider %q: %w
- %w (root key): %w
- %w (rsa key): %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/3ee710d6b7395c7f.
Report an issue: GitHub.