elsa-workflows/elsa-core · critical · InvalidOperationException
Elsa Secrets encryption key must be exactly 16, 24, or 32…
Error message
Elsa Secrets encryption key must be exactly 16, 24, or 32 bytes.
What it means
GetKey validates that SecretsOptions.EncryptionKey is exactly 16, 24, or 32 bytes (AES-128/192/256 key sizes) and throws InvalidOperationException otherwise. A key of any other length cannot be used with the AES-GCM cipher used by the protector.
Solutions
- Derive a properly sized key: use a KDF (e.g. Rfc2898DeriveBytes/argon2) or SHA-256 hash to get exactly 32 bytes.
- Ensure base64-encoded keys are decoded to bytes before assignment (Encoding/Convert.FromBase64String).
- Generate a fresh key of exactly 32 bytes (RandomNumberGenerator.GetBytes(32)) if no prior encrypted data exists.
- Caution: changing the key makes previously encrypted payloads undecryptable — re-encrypt secrets after changing keys.
Example fix
// before
options.EncryptionKey = Encoding.UTF8.GetBytes("my-secret-passphrase"); // 20 bytes -> throws
// after
using var kdf = new Rfc2898DeriveBytes("my-secret-passphrase", salt, 100_000, HashAlgorithmName.SHA256);
options.EncryptionKey = kdf.GetBytes(32); // exactly 32 bytes Defensive patterns
Strategy: validation
Validate before calling
var key = options.EncryptionKey;
if (key is not { Length: 16 or 24 or 32 })
throw new InvalidOperationException($"EncryptionKey must be 16/24/32 bytes; got {key?.Length ?? 0}."); Type guard
bool IsValidKey(byte[]? key) => key is { Length: 16 or 24 or 32 }; Try / catch
try { var value = protector.Protect(plaintext); }
catch (InvalidOperationException ex) when (ex.Message.Contains("16, 24, or 32 bytes"))
{ logger.LogCritical("Secrets encryption key has invalid length: {Msg}", ex.Message); throw; } Prevention
- Generate keys with RandomNumberGenerator.GetBytes(32)
- Always base64-decode encoded keys before assigning to byte[]
- Use a KDF for passphrase-derived keys
- Never assign raw passphrase bytes directly
- Re-encrypt secrets after any key change
When it happens
Trigger: Setting SecretsOptions.EncryptionKey to a byte array whose length is not 16, 24, or 32 — commonly a raw UTF-8 password of arbitrary length, or a base64 string that was not decoded / decoded incorrectly.
Common situations: Passing a passphrase string directly instead of a properly sized key; double-encoding base64; truncating a key during copy/paste; generating a 40-byte key from a wrong hash output.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- A value is required for encrypted secrets.
- Elsa Secrets encryption key is not configured. Configure…
- The protected secret payload is not supported.
- A configuration key is required.
- A managed secret writer returned the live secret reference…
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/3b7e3b2820b74d9d.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Secrets/Services/DefaultSecretValueProtector.cs:48
var nonce = Convert.FromBase64String(parts[1]);
var tag = Convert.FromBase64String(parts[2]);
var ciphertext = Convert.FromBase64String(parts[3]);
var plaintext = new byte[ciphertext.Length];
using var aes = new AesGcm(GetKey(), TagSize);
aes.Decrypt(nonce, ciphertext, tag, plaintext);
return System.Text.Encoding.UTF8.GetString(plaintext);
}
private byte[] GetKey()
{
var key = options.Value.EncryptionKey;
if (key == null || key.Length == 0)
throw new InvalidOperationException("Elsa Secrets encryption key is not configured. Configure SecretsOptions.EncryptionKey before using the encrypted secrets store.");
if (key.Length is not (16 or 24 or 32))
throw new InvalidOperationException("Elsa Secrets encryption key must be exactly 16, 24, or 32 bytes.");
return key;
}
}
View on GitHub (pinned to fe9217bdfa)