mastra-ai/mastra · critical
Telegram installation secrets are encrypted at rest, but no
Error message
Telegram installation secrets are encrypted at rest, but no encryption key is configured. Set `encryptionKey` on TelegramProvider or MASTRA_ENCRYPTION_KEY.
What it means
Telegram installation secrets (bot tokens) are encrypted at rest with encrypt(). When the store reads a record whose secret carries the encrypted marker but the TelegramProvider/store has no encryptionKey (neither constructor option nor MASTRA_ENCRYPTION_KEY), it cannot decrypt, so it throws instead of returning ciphertext as if it were a token. Passing ciphertext through unchanged would produce hopeless downstream auth failures, hence the fail-fast.
Source
Thrown at channels/telegram/src/install-store.ts:68
const records = await this.storage.listInstallations(PLATFORM);
return records.map(r => this.#fromRecord(r));
}
/** Remove an agent's installation, if present. */
async deleteByAgent(agentId: string): Promise<void> {
const record = await this.storage.getInstallationByAgent(PLATFORM, agentId);
if (record) await this.storage.deleteInstallation(record.id);
}
#enc(value: string | undefined): string | undefined {
return value && this.encryptionKey ? encrypt(value, this.encryptionKey) : value;
}
#dec(value: string | undefined): string | undefined {
if (!value) return value;
if (!this.encryptionKey) {
if (isEncrypted(value)) {
throw new Error(
'Telegram installation secrets are encrypted at rest, but no encryption key is configured. Set `encryptionKey` on TelegramProvider or MASTRA_ENCRYPTION_KEY.',
);
}
return value;
}
return decrypt(value, this.encryptionKey);
}
#toRecord(install: TelegramInstallation): ChannelInstallation {
const data: TelegramInstallationData = {
botToken: this.#enc(install.botToken),
secretToken: this.#enc(install.secretToken),
username: install.username,
webhookUrl: install.webhookUrl,
commands: install.commands,
};
return {
id: install.id,View on GitHub (pinned to 75dd419e61)
Solutions
- Set MASTRA_ENCRYPTION_KEY in the environment to the same key used when the installation was saved.
- Pass encryptionKey explicitly: new TelegramProvider({ encryptionKey }) / store option.
- If the key is truly lost, delete the encrypted installation records and re-install the Telegram bot to re-encrypt with the new key.
- Keep the key stable across environments (secret manager) to avoid re-encryption churn.
Example fix
// before
const provider = new TelegramProvider({});
// after
const provider = new TelegramProvider({
encryptionKey: process.env.MASTRA_ENCRYPTION_KEY,
}); Defensive patterns
Strategy: validation
Validate before calling
const encryptionKey = process.env.MASTRA_ENCRYPTION_KEY;
if (!encryptionKey) {
throw new Error('MASTRA_ENCRYPTION_KEY must be set to read Telegram installations');
}
const provider = new TelegramProvider({ encryptionKey }); Try / catch
try {
const botToken = store.getBotToken(agentId);
} catch (e) {
if (e instanceof Error && e.message.includes('no encryption key is configured')) {
console.error('Set MASTRA_ENCRYPTION_KEY to the key used when this installation was saved');
} else throw e;
} Prevention
- Provision MASTRA_ENCRYPTION_KEY identically across dev/staging/prod via a secret manager.
- Add a startup health check that fails boot when the key is absent but encrypted records exist.
- Back up the key securely; if lost, encrypted installations must be re-created.
When it happens
Trigger: Loading/reading a stored Telegram installation whose secret was saved encrypted, while the current process was started without MASTRA_ENCRYPTION_KEY and without encryptionKey on TelegramProvider.
Common situations: Deploying to a new environment (CI, staging) where the MASTRA_ENCRYPTION_KEY env var wasn't copied; rotating keys infra and forgetting the env var; running locally against a prod database whose records were encrypted.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- TelegramProvider needs a baseUrl to register a webhook. Set
- Cookie password must be at least 32 characters for SSO. Set
- Cookie password must be at least 32 characters for SSO. Set
- Invalid ciphertext payload
- Telegram getMe returned a non-bot user; expected a BotFather
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/69202d65b303c9eb.
Report an issue: GitHub.