hashicorp/nomad · error

failed to encrypt rsa key: %w

Error message

failed to encrypt rsa key: %w

What it means

Cipher sets created after Nomad 1.7.0 carry an RSA key (used for signing workload-identity JWTs) alongside the root key. encryptDEK re-encrypts this RSA key with the same KEK wrapper; failure is wrapped as "failed to encrypt rsa key". The root key blob succeeded, but the full KEKWrapper cannot be completed.

Source

Thrown at nomad/encrypter.go:890

	rootBlob, err := wrapper.Encrypt(e.srv.shutdownCtx, rootKey.Key)
	if err != nil {
		return nil, fmt.Errorf("failed to encrypt root key: %w", err)
	}

	kekWrapper := &structs.WrappedKey{
		Provider:                 provider.Provider.String(),
		ProviderID:               provider.ID(),
		WrappedDataEncryptionKey: rootBlob,
		WrappedRSAKey:            &kms.BlobInfo{},
		KeyEncryptionKey:         kek,
	}

	// Only cipherSets created after 1.7.0 will contain an RSA key.
	if len(rootKey.RSAKey) > 0 {
		rsaBlob, err := wrapper.Encrypt(e.srv.shutdownCtx, rootKey.RSAKey)
		if err != nil {
			return nil, fmt.Errorf("failed to encrypt rsa key: %w", err)
		}
		kekWrapper.WrappedRSAKey = rsaBlob
	}

	return kekWrapper, nil
}

func (e *Encrypter) writeKeyToDisk(
	meta *structs.RootKeyMeta, provider *structs.KEKProviderConfig,
	wrappedKey *structs.WrappedKey, kek []byte) (string, error) {

	// the on-disk keystore flattens the keys wrapped for the individual
	// KMS providers out to their own files
	diskWrapper := &structs.KeyEncryptionKeyWrapper{
		Meta:                     meta,
		Provider:                 provider.Name,
		ProviderID:               provider.ID(),
		WrappedDataEncryptionKey: wrappedKey.WrappedDataEncryptionKey,

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Retry the wrap operation — the root-key encrypt succeeded previously, so transient errors are plausible.
  2. Check KMS provider payload size limits vs. the RSA key blob size.
  3. Verify credentials/permissions are still valid at the time of the second call.
  4. Check backend logs for rate limiting or throttling responses.
Defensive patterns

Strategy: retry

Try / catch

blob, err := encryptDEK(...)
if err != nil && strings.Contains(err.Error(), "failed to encrypt rsa key") {
    // retry with backoff; check KMS payload-size limits and throttling
}

Prevention

When it happens

Trigger: wrapper.Encrypt(e.srv.shutdownCtx, rootKey.RSAKey) returns an error while the root key has a non-empty RSAKey — same KMS failure modes as the root key encrypt but during the second Encrypt call.

Common situations: Transient KMS backend error or credential expiry between the two Encrypt calls; payload-size limits on the KMS provider if the RSA key is large; rate limiting on the KMS API.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/e08353df5990826a. Report an issue: GitHub.