actualbudget/actual · error · Error
load-key-error
load-key-error
Error message
load-key-error
What it means
During initApp, Actual loads per-file encryption keys from the sync server via encryption.loadKey. If any key fails to load or decrypt (wrong password, corrupt key blob, key missing), the error is logged and this coded error is thrown so the client can map it to a user-facing message.
Source
Thrown at packages/loot-core/src/server/main.ts:208
await sqlite.init();
asyncStorage.init();
await fs.init();
await setupDocumentsDir();
const keysStr = await asyncStorage.getItem('encrypt-keys');
if (keysStr) {
try {
const keys = JSON.parse(keysStr);
// Load all the keys
await Promise.all(
Object.keys(keys).map(fileId => {
return encryption.loadKey(keys[fileId]);
}),
);
} catch (e) {
logger.log('Error loading key', e);
throw new Error('load-key-error');
}
}
const url = await asyncStorage.getItem('server-url');
if (!url) {
await asyncStorage.removeItem('user-token');
}
setServer(url);
connection.init(socketName, app.handlers);
// Allow running DB queries locally
global.$query = aqlQuery;
global.$q = q;
if (isDev) {
global.$send = (name, args) => runHandler(app.handlers[name], args);View on GitHub (pinned to d4334cb6e6)
Solutions
- Enter the correct encryption password for the budget when prompted (the key was encrypted with the original password).
- If the password was changed, re-set it from the client that can still open the budget so the server key matches.
- Check the server logs for the logged 'Error loading key' detail to distinguish corrupt key data from a wrong password.
- If the key is unrecoverable, restore the affected files/key store from a server backup, or reset end-to-end encryption (accepting that old encrypted data may be lost).
Defensive patterns
Strategy: try-catch
Validate before calling
// before opening a budget, confirm the server is reachable and key exists
const res = await fetch(`${serverUrl}/status`);
if (!res.ok) throw new Error('sync server unreachable'); Try / catch
try {
await initApp();
} catch (e) {
if (e.message === 'load-key-error') {
// prompt user for the budget's encryption password or check server key files
} else throw e;
} Prevention
- Never change a budget's encryption password from multiple clients independently.
- Back up the server's user-files/key store together with budget data.
- Keep all clients on the same Actual version when using end-to-end encryption.
- Check server logs ('Error loading key') at the first sign of decryption failures.
When it happens
Trigger: Opening a budget whose encryption key file on the server cannot be decrypted — e.g. the user changed or forgot the budget's end-to-end encryption password, or the key record is missing/corrupt in the server's key store.
Common situations: Changing the encryption password in one client while another client still caches the old one; restoring a server from backup without the key files; server data dir partially deleted; decrypting with a different password than the one used to encrypt.
Related errors
- No sync server configured.
- No id returned from download.
- response.reason || response.error_code
- response.reason || response.error || fallbackMessage
- Failed to get server config.
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/50cdaba4233e5c9c.
Report an issue: GitHub.