{"record":{"id":"875b48c6785d1f60","repo":"elsa-workflows/elsa-core","slug":"the-protected-secret-payload-is-not-supported","errorCode":null,"errorMessage":"The protected secret payload is not supported.","messagePattern":"The protected secret payload is not supported\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Secrets/Services/DefaultSecretValueProtector.cs","lineNumber":28,"sourceCode":"\n    public string Protect(string value)\n    {\n        var nonce = RandomNumberGenerator.GetBytes(NonceSize);\n        var plaintext = System.Text.Encoding.UTF8.GetBytes(value);\n        var ciphertext = new byte[plaintext.Length];\n        var tag = new byte[TagSize];\n\n        using var aes = new AesGcm(GetKey(), TagSize);\n        aes.Encrypt(nonce, plaintext, ciphertext, tag);\n\n        return string.Join(\".\", \"v1\", Convert.ToBase64String(nonce), Convert.ToBase64String(tag), Convert.ToBase64String(ciphertext));\n    }\n\n    public string Unprotect(string protectedValue)\n    {\n        var parts = protectedValue.Split('.');\n        if (parts.Length != 4 || parts[0] != \"v1\")\n            throw new InvalidOperationException(\"The protected secret payload is not supported.\");\n\n        var nonce = Convert.FromBase64String(parts[1]);\n        var tag = Convert.FromBase64String(parts[2]);\n        var ciphertext = Convert.FromBase64String(parts[3]);\n        var plaintext = new byte[ciphertext.Length];\n\n        using var aes = new AesGcm(GetKey(), TagSize);\n        aes.Decrypt(nonce, ciphertext, tag, plaintext);\n\n        return System.Text.Encoding.UTF8.GetString(plaintext);\n    }\n\n    private byte[] GetKey()\n    {\n        var key = options.Value.EncryptionKey;\n        if (key == null || key.Length == 0)\n            throw new InvalidOperationException(\"Elsa Secrets encryption key is not configured. Configure SecretsOptions.EncryptionKey before using the encrypted secrets store.\");\n","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Secrets/Services/DefaultSecretValueProtector.cs#L10-L46","documentation":"DefaultSecretValueProtector.Unprotect parses protected values of the form 'v1.<nonce>.<tag>.<ciphertext>' (4 dot-separated base64 parts). Values that do not match this exact versioned envelope are rejected with InvalidOperationException. Typically the value was not produced by this protector (plaintext, or encrypted by a different tool/format).","triggerScenarios":"Unprotect (or decrypting resolve paths) receiving a string that is not 4 dot-separated parts or whose prefix is not 'v1' — e.g. a plaintext secret pasted into an encrypted field, or a payload from another/older encryption scheme.","commonSituations":"Storing raw plaintext where the store expects protector output; encryption format version bumped; values encrypted by a previous implementation or external tool; copy/paste corruption dropping characters.","solutions":["Encrypt the plaintext value with the protector (Protect) before storing it.","Confirm the stored value came from the same protector version ('v1') and re-encrypt with the current version if not.","Re-enter the protected value without corruption (check for trimmed/stripped characters).","If migrating formats, write a migration that decrypts with the old scheme and re-protects with v1."],"exampleFix":"// before\nawait secretManager.CreateSecretAsync(new CreateSecretRequest { Name = \"ApiKey\", PlainTextValue = \"sk-live-abc123\" }); // plaintext into encrypted path\n// after\nvar protectedValue = protector.Protect(\"sk-live-abc123\");\nawait secretManager.CreateSecretAsync(new CreateSecretRequest { Name = \"ApiKey\", ProtectedValue = protectedValue });","handlingStrategy":"type-guard","validationCode":"static bool IsProtectedFormat(string value)\n{\n    var parts = value.Split('.');\n    return parts.Length == 4 && parts[0] == \"v1\" &&\n           parts.Skip(1).All(p => Convert.TryFromBase64String(p, new byte[p.Length * 3 / 4 + 3], out _));\n}","typeGuard":"bool LooksProtected(string? value) =>\n    !string.IsNullOrWhiteSpace(value) && value.Split('.').Length == 4 && value.StartsWith(\"v1.\", StringComparison.Ordinal);","tryCatchPattern":"try { var plain = protector.Unprotect(stored); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"not supported\"))\n{ logger.LogError(\"Value for secret is not in v1 protected format; re-encrypt it\"); throw; }","preventionTips":["Always run plaintext through Protect before storing in encrypted fields","Version-tag future format changes and handle them explicitly","Validate pasted values match the v1 envelope","Re-protect values when migrating between encryption schemes"],"tags":["secrets","encryption","format"],"backgroundTag":"invalid-argument-format","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}