mastra-ai/mastra · error

[FactorySecretEncryption] Key id is required.

Error message

[FactorySecretEncryption] Key id is required.

What it means

Factory secret encryption uses AES-256-GCM with envelope encryption keyed by a stable key id (the id is stamped into envelopes so older keys in `previous` can decrypt). validateKey() throws when the configured key's id is empty/missing, because envelopes could not be attributed or rotated without it.

Source

Thrown at mastracode/factory/src/secret-encryption.ts:36

/** Encrypts opaque JSON values before they cross the Factory storage boundary. */
export interface FactorySecretEncryption {
  encrypt<T>(value: T): Promise<string>;
  decrypt<T>(value: unknown): Promise<DecryptedFactorySecret<T>>;
}

export interface FactorySecretEncryptionKey {
  id: string;
  key: Uint8Array;
}

export interface FactorySecretEncryptionConfig {
  primary: FactorySecretEncryptionKey;
  previous?: FactorySecretEncryptionKey[];
}

function validateKey({ id, key }: FactorySecretEncryptionKey): Buffer {
  if (!id) throw new Error('[FactorySecretEncryption] Key id is required.');
  const buffer = Buffer.from(key);
  if (buffer.byteLength !== 32) {
    throw new Error(`[FactorySecretEncryption] Key "${id}" must be exactly 32 bytes.`);
  }
  return buffer;
}

function parseEnvelope(value: string): SecretEnvelopeV1 {
  let parsed: unknown;
  try {
    parsed = JSON.parse(Buffer.from(value.slice(ENVELOPE_PREFIX.length), 'base64url').toString('utf8'));
  } catch {
    throw new Error('[FactorySecretEncryption] Invalid encrypted value.');
  }

  if (
    !parsed ||
    typeof parsed !== 'object' ||

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Set a non-empty id (e.g. 'k-2026-01') on the primary FactorySecretEncryptionKey.
  2. If the id comes from an env var (e.g. SECRET_KEY_ID), verify it is set in the deployment environment.
  3. Check that parsed JSON/env config actually populates the id field, not just the key bytes.
  4. When rotating, ensure both old and new keys retain their original stable ids.

Example fix

// before
createFactorySecretEncryption({
  primary: { id: process.env.SECRET_KEY_ID ?? '', key: keyBytes }, // empty id
});

// after
const id = process.env.SECRET_KEY_ID;
if (!id) throw new Error('SECRET_KEY_ID must be set');
createFactorySecretEncryption({ primary: { id, key: keyBytes } });
Defensive patterns

Strategy: validation

Validate before calling

function assertEncryptionKey(cfg: { id?: unknown; key: Uint8Array }): void {
  if (!cfg.id || typeof cfg.id !== 'string') throw new Error('SECRET_KEY_ID (key id) must be a non-empty string');
  if (Buffer.from(cfg.key).byteLength !== 32) throw new Error('encryption key must be exactly 32 bytes');
}
// run over primary and every previous entry before createFactorySecretEncryption

Type guard

function isFactorySecretEncryptionKey(v: unknown): v is { id: string; key: Uint8Array } {
  return typeof v === 'object' && v !== null && typeof (v as any).id === 'string' && (v as any).id.length > 0 && (v as any).key instanceof Uint8Array;
}

Try / catch

try {
  const enc = createFactorySecretEncryption({ primary, previous });
} catch (err) {
  if (err instanceof Error && err.message === '[FactorySecretEncryption] Key id is required.') {
    console.error('Check SECRET_KEY_ID env var / config: every key needs a stable non-empty id');
  } else throw err;
}

Prevention

When it happens

Trigger: Calling createFactorySecretEncryption (directly or via primaryKey) with primary (or a previous entry) whose FactorySecretEncryptionKey.id is undefined, null, or an empty string.

Common situations: Loading keys from env vars where the id var is unset (missing-env-var); building the config programmatically and forgetting the id field; JSON config with an empty id string; a migration/rotation script that copies only the key bytes.

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/67ae2ccfe442e78e. Report an issue: GitHub.