mgth/LittleBigMouse · error · CryptographicException
Payload was protected with
Error message
Payload was protected with '{scheme}', unreadable on this system. What it means
Envelopes are self-describing ('LBM1.<scheme>.<base64>'). Unprotect only understands 'dpapi' (on Windows) and 'aesgcm' (anywhere); any other scheme hits this default case and throws a CryptographicException naming the scheme. It exists so a payload carried to a machine that cannot read it fails loudly instead of silently decoding to garbage.
Solutions
- Re-create the secret on this machine: delete the stored envelope and re-enter/re-pair so Protect seals it with a scheme this system supports.
- If it is a dpapi envelope, open the data file on Windows (or with the same user account on Windows) and migrate the value to clear text or re-protect it there.
- If caused by a version downgrade, upgrade back to the version that wrote the envelope.
- Check the envelope string is intact (starts with 'LBM1.' followed by dpapi or aesgcm) in case the file was corrupted or truncated in transfer.
Example fix
// before
var token = protector.Unprotect(envelopeFromSyncedProfile); // dpapi envelope on Linux
// after
if (envelope.StartsWith("LBM1.dpapi.") && !OperatingSystem.IsWindows())
token = RePairDevice(); // scheme unreadable here — obtain it fresh
else
token = protector.Unprotect(envelope); Defensive patterns
Strategy: type-guard
Validate before calling
static bool SchemeSupportedHere(string envelope) =>
!SecretProtector.IsProtected(envelope) ||
(envelope.StartsWith("LBM1.dpapi.") && OperatingSystem.IsWindows()) ||
envelope.StartsWith("LBM1.aesgcm."); Type guard
static bool IsReadableOnThisSystem(string envelope)
{
if (!SecretProtector.IsProtected(envelope)) return true; // clear text
var scheme = envelope[5..envelope.IndexOf('.')];
return scheme switch
{
"dpapi" => OperatingSystem.IsWindows(),
"aesgcm" => true,
_ => false
};
} Try / catch
try { return protector.Unprotect(envelope); }
catch (CryptographicException ex) when (ex.Message.Contains("unreadable on this system"))
{ return ReCreateSecret(); /* scheme unsupported here */ } Prevention
- Do not sync secret-bearing config files between Windows and Unix profiles; re-pair per platform.
- Before restoring a backup on a different OS, strip or migrate protected envelopes first.
- Pin major versions: envelopes written by a newer scheme cannot be read after a downgrade.
- Prefer clear-text migration on export (with user consent) over moving dpapi envelopes cross-platform.
When it happens
Trigger: Calling Unprotect on an envelope whose scheme token is neither 'dpapi' nor 'aesgcm' — e.g. a 'dpapi' envelope from a Windows profile opened on Linux/macOS, an envelope produced by a newer version with an added scheme, or a hand-edited/corrupted scheme field.
Common situations: Syncing or copying the config directory between Windows and Unix machines; restoring a Windows-encrypted settings file on Linux; upgrading from a future version that introduced a new scheme and then downgrading; manual editing of the envelope string.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- Not a protected payload.
- Protected payload has no scheme.
- Protected payload is truncated.
- No key at to read this payload with.
AI-assisted analysis of mgth/LittleBigMouse@7a42f01d47 (2026-09-16).
Data as JSON: /api/errors/4b0b4d1351c54327.
Report an issue: GitHub.
Appendix: source
Thrown at LittleBigMouse.Plugins/LittleBigMouse.Plugins.Core/SecretProtector.cs:120
case AesGcmScheme:
if (payload.Length < NonceLength + TagLength)
throw new CryptographicException("Protected payload is truncated.");
var plain = new byte[payload.Length - NonceLength - TagLength];
using (var aes = new AesGcm(ReadKey() ?? throw new CryptographicException(
$"No key at {_keyFilePath} to read this payload with."), TagLength))
{
aes.Decrypt(
payload.AsSpan(0, NonceLength),
payload.AsSpan(NonceLength + TagLength),
payload.AsSpan(NonceLength, TagLength),
plain);
}
return Encoding.UTF8.GetString(plain);
default:
throw new CryptographicException(
$"Payload was protected with '{scheme}', unreadable on this system.");
}
}
byte[] GetOrCreateKey()
{
lock (_keyLock)
{
return _key ??= ReadKeyLocked() ?? CreateKeyLocked();
}
}
byte[]? ReadKey()
{
lock (_keyLock)
{
return _key ??= ReadKeyLocked();
}View on GitHub (pinned to 7a42f01d47)