elsa-workflows/elsa-core · critical · InvalidOperationException
Elsa Secrets encryption key is not configured. Configure…
Error message
Elsa Secrets encryption key is not configured. Configure SecretsOptions.EncryptionKey before using the encrypted secrets store.
What it means
GetKey reads SecretsOptions.EncryptionKey and throws InvalidOperationException when it is null or empty. The AES-GCM protector cannot encrypt or decrypt without a key, so the library fails fast instead of silently using an insecure default. Message explicitly names the option to configure.
Solutions
- Configure SecretsOptions.EncryptionKey (16/24/32 bytes) at startup, e.g. services.Configure<SecretsOptions>(o => o.EncryptionKey = key).
- Bind the key from configuration or environment (e.g. base64-decode ELISA_SECRETS_KEY) into options.
- Add the key to the deployment's secret store (Azure Key Vault, Kubernetes secret, user-secrets in dev).
- Add a startup validation check so the app fails fast with a clear message when the key is absent.
Example fix
// before builder.Services.AddSecrets(); // EncryptionKey never set // after var key = Convert.FromBase64String(builder.Configuration["Elsa:Secrets:EncryptionKey"]!); builder.Services.Configure<SecretsOptions>(o => o.EncryptionKey = key); // 16/24/32 bytes
Defensive patterns
Strategy: validation
Validate before calling
var key = configuration["Elsa:Secrets:EncryptionKey"];
if (string.IsNullOrWhiteSpace(key))
throw new InvalidOperationException("Set Elsa:Secrets:EncryptionKey (base64, 16/24/32 bytes) before using encrypted secrets.");
services.Configure<SecretsOptions>(o => o.EncryptionKey = Convert.FromBase64String(key)); Type guard
bool KeyConfigured(SecretsOptions o) => o.EncryptionKey is { Length: > 0 }; Try / catch
try { var value = protector.Unprotect(stored); }
catch (InvalidOperationException ex) when (ex.Message.Contains("encryption key is not configured"))
{ logger.LogCritical("Secrets encryption key missing; check deployment configuration"); throw; } Prevention
- Validate options at startup with IValidateOptions/ValidateOnStart
- Store the key in the platform secret manager (Key Vault/K8s secret/user-secrets)
- Map env vars into SecretsOptions explicitly
- Add the key to deployment checklists
When it happens
Trigger: Any Protect/Unprotect call (encrypted secret store reads/writes, HmacExternalAuthenticationHandleHasher) when SecretsOptions.EncryptionKey was not set in DI configuration.
Common situations: Forgetting to bind SecretsOptions in Program.cs; key provided via env var not mapped to options; Developer/Production config sections missing; new deployment without the key in secret management.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- A value is required for encrypted secrets.
- Elsa Secrets encryption key must be exactly 16, 24, or 32…
- The configured secret binding could not be resolved.
- The protected secret payload is not supported.
- A configuration key is required.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/3d369b0f3b078989.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Secrets/Services/DefaultSecretValueProtector.cs:45
if (parts.Length != 4 || parts[0] != "v1")
throw new InvalidOperationException("The protected secret payload is not supported.");
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)