usebruno/bruno · error · Error
AES256 decryption failed: ${fallbackErr.message}
Error message
AES256 decryption failed: ${fallbackErr.message} What it means
Thrown by aes256Decrypt when both the new SHA256-key decryption and the legacy MD5-based deriveKeyAndIv decryption fail. The two-step attempt exists to read blobs encrypted before the key-derivation changed. Failure means the data could not be unwrapped with either the current or the legacy scheme using the supplied key.
Source
Thrown at packages/bruno-electron/src/utils/encryption.js:65
const iv = Buffer.alloc(16, 0); // Default IV for new encryption
const key = crypto.createHash('sha256').update(rawKey).digest(); // Derive a 32-byte key
try {
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(data, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
} catch (err) {
// If decryption fails, fall back to old key derivation
try {
const { key: oldKey, iv: oldIv } = deriveKeyAndIv(rawKey, 32, 16);
const decipher = crypto.createDecipheriv('aes-256-cbc', oldKey, oldIv);
const decrypted = decipher.update(data, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
} catch (fallbackErr) {
console.error('AES256 decryption failed with both methods:', err, fallbackErr);
throw new Error('AES256 decryption failed: ' + fallbackErr.message);
}
}
}
// electron safe storage encryption and decryption functions
function safeStorageEncrypt(str) {
let encryptedStringBuffer = safeStorage.encryptString(str);
// Convert the encrypted buffer to a hexadecimal string
const encryptedString = encryptedStringBuffer.toString('hex');
return encryptedString;
}
function safeStorageDecrypt(str) {
try {
// Convert the hexadecimal string to a buffer
const encryptedStringBuffer = Buffer.from(str, 'hex');
View on GitHub (pinned to 9bdd81c7bd)
Solutions
- Ensure the same passkey used to encrypt is supplied to decrypt (for AES256_ALGO passkey-protected values).
- For machine-bound secrets, decrypt on the originating machine or re-encrypt with an explicit passkey before migrating.
- If the value is irrecoverable, treat it as lost and re-enter the secret through the UI.
- Verify the stored hex is intact (even length, no whitespace).
Example fix
// before
try {
// new method
} catch (err) {
try {
// legacy method
} catch (fallbackErr) {
throw new Error('AES256 decryption failed: ' + fallbackErr.message);
}
}
// after: prefer decryptStringSafe at call sites
const { success, value, error } = decryptStringSafe(stored);
if (!success) return { recoverable: false, reason: error }; Defensive patterns
Strategy: fallback
Validate before calling
const { success, value, error } = decryptStringSafe(stored);
if (!success) {
// wrong passkey or wrong machine; re-prompt the user
return await promptUserToReenterSecret();
} Type guard
function looksLikeAes256Cipher(str) {
return typeof str === 'string' && str.startsWith('$01:') && str.length > 4 && str.length % 2 === 0;
} Try / catch
try {
return aes256Decrypt(data, passkey);
} catch (err) {
if (err.message.startsWith('AES256 decryption failed')) {
// value is irrecoverable on this machine/passkey; re-create the secret
return null;
}
throw err;
} Prevention
- Use a stable explicit passkey rather than machineIdSync for secrets that may migrate.
- Re-encrypt secrets on the source machine before moving them.
- Prefer decryptStringSafe at call sites to convert failures into recoverable results.
When it happens
Trigger: Passing the wrong passkey (or the wrong machineIdSync-derived key) for an AES256_ALGO ('$01:...') blob; data corrupted/truncated; value migrated across machines whose machine-id differs and no passkey was supplied.
Common situations: Copying encrypted secrets between machines without the originating machine-id; passkey mismatch after a credentials reset; partial hex corruption from a bad copy/paste; version downgrade trying to read data encrypted by a newer scheme.
Related errors
- SafeStorage decryption failed: ${err.message}
- Decrypt failed: unrecognized string format
- Decrypt failed: Invalid algo
- EdgeGrid: clientSecret is required
- Client ID is required for OAuth2 client credentials flow
AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13).
Data as JSON: /api/errors/ac37757c99a2e751.
Report an issue: GitHub.