FuelLabs/fuels-ts · error · FuelError
INVALID_PASSWORD
INVALID_PASSWORD
Error message
Failed to decrypt the keystore wallet, the provided password is incorrect.
What it means
Thrown by decryptKeystoreWallet() when the MAC verification fails. After deriving the scrypt key from the supplied password and the keystore's salt, the code computes Keccak-256 over the second half of the key concatenated with the ciphertext and compares it to the stored 'mac'. A mismatch proves the password is wrong (or the keystore is corrupted) — decryption is aborted before any private key is exposed.
Source
Thrown at packages/account/src/wallet/keystore-wallet.ts:151
const key = scrypt({
password: passwordBuffer,
salt: saltBuffer,
n,
p,
r,
dklen,
});
// Verify the MAC. It should be the Keccak-256 hash of the concatenation of the second half of the derived key and the ciphertext.
const data = Uint8Array.from([...key.subarray(16, 32), ...ciphertextBuffer]);
const macHashUint8Array = keccak256(data);
const macHash = stringFromBuffer(macHashUint8Array, 'hex');
if (mac !== macHash) {
throw new FuelError(
ErrorCode.INVALID_PASSWORD,
'Failed to decrypt the keystore wallet, the provided password is incorrect.'
);
}
// Decrypt the private key.
const buffer = await decryptJsonWalletData(ciphertextBuffer, key, ivBuffer);
const privateKey = hexlify(buffer);
return privateKey;
}
View on GitHub (pinned to b3f37c91ac)
Solutions
- Re-enter the password carefully, watching for trailing spaces or autocorrect.
- If the password is forgotten, the keystore is unrecoverable — restore from a backup or seed phrase.
- Verify the keystore JSON is intact (valid JSON, all crypto fields present, not truncated).
- Confirm the keystore was produced by this SDK's encryptKeystoreWallet (same scrypt/AES-128-CTR scheme).
- Strip accidental whitespace/newlines from the password string before passing it in.
Example fix
// before const wallet = await WalletUnlocked.loadKeystore(path, 'wrong-password'); // after const password = userInput.trim(); const wallet = await WalletUnlocked.loadKeystore(path, password);
Defensive patterns
Strategy: try-catch
Try / catch
try {
return await decryptKeystoreWallet(json, password);
} catch (err) {
if (err instanceof FuelError && err.code === ErrorCode.INVALID_PASSWORD) {
// prompt user for password again; do not expose whether mac vs ciphertext failed
}
throw err;
} Prevention
- Trim and validate password input before decryption.
- Verify the keystore JSON is complete and uncorrupted before attempting.
- Confirm the keystore was produced by the same SDK encryption scheme.
When it happens
Trigger: Calling decryptKeystoreWallet(jsonWallet, password) — directly or via Wallet.fromKeystoreWallet / WalletUnlocked.loadKeystore — with a password that does not match the one used in encryptKeystoreWallet. Also if the keystore JSON was tampered with (ciphertext, salt, or mac altered).
Common situations: Wrong password typed by the user; password changed but the old keystore file was retained; keystore file corrupted on disk or truncated during copy; cross-tool import where a different KDF/cipher was assumed; trailing whitespace in the password input.
Related errors
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/86f49d80299185fe.
Report an issue: GitHub.