transloadit/uppy · error · Error

Invalid encrypted value. Maybe it was generated with an old

Error message

Invalid encrypted value. Maybe it was generated with an old Companion version?

What it means

Companion encrypts provider OAuth tokens before storing them in its database using AES-GCM with a key derived from COMPANION_SECRET. During decryption, the stored value is split into nonce and ciphertext; if the nonce is shorter than the required 12 bytes, the payload's structure doesn't match the expected format, and this error is thrown suggesting it came from an older Companion version.

Source

Thrown at packages/@uppy/companion/src/server/helpers/utils.ts:136

export const decrypt = (encrypted: string, secret: string | Buffer): string => {
  const nonceHexLength = nonceLength * 2 // because hex encoding uses 2 bytes per byte
  // NOTE: The first 32 characters are the nonce, in hex format.
  const nonce = Buffer.from(encrypted.slice(0, nonceHexLength), 'hex')
  // The rest is the encrypted string, in base64url format.
  const encryptionWithoutNonce = Buffer.from(
    encrypted.slice(nonceHexLength),
    'base64url',
  )
  // The last 16 bytes of the rest is the authentication tag
  const authTag = encryptionWithoutNonce.subarray(-authTagLength)
  // and the rest (from beginning) is the encrypted data
  const encryptionWithoutNonceAndTag = encryptionWithoutNonce.subarray(
    0,
    -authTagLength,
  )

  if (nonce.length < nonceLength) {
    throw new Error(
      'Invalid encrypted value. Maybe it was generated with an old Companion version?',
    )
  }

  const { key, iv } = createSecrets(secret, nonce)

  const decipher = crypto.createDecipheriv('aes-256-ccm', key, iv, {
    authTagLength,
  })
  decipher.setAuthTag(authTag)

  const decrypted = Buffer.concat([
    decipher.update(encryptionWithoutNonceAndTag),
    decipher.final(),
  ])
  return decrypted.toString('utf8')
}

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Most likely: clear the stale token store (drop the companion.tokens table / flush the relevant storage) so users simply re-authenticate
  2. Keep COMPANION_SECRET stable across deployments — verify it wasn't rotated accidentally
  3. If upgrading from a very old Companion, follow the release notes migration path or wipe persisted tokens as part of the upgrade
  4. Re-authenticate the affected providers after clearing tokens

Example fix

# before
COMPANION_SECRET=new-secret uppy-companion  # old tokens now fail to decrypt

# after
# wipe stored tokens once, then restart with a stable secret
redis-cli --scan --pattern 'companion:*' | xargs redis-cli del
COMPANION_SECRET=new-secret uppy-companion
Defensive patterns

Strategy: fallback

Validate before calling

// Assert expected secret/token-store compatibility at startup
if (!process.env.COMPANION_SECRET || process.env.COMPANION_SECRET.length < 16) {
  throw new Error('COMPANION_SECRET must be set and stable')
}

Type guard

function isLegacyEncryptionError(err: unknown): boolean {
  return err instanceof Error && err.message.includes('Invalid encrypted value')
}

Try / catch

try {
  const token = await companion.tokenStore.get(id)
} catch (err) {
  if (isLegacyEncryptionError(err)) {
    await companion.tokenStore.delete(id) // force re-auth
    return null
  }
  throw err
}

Prevention

When it happens

Trigger: Running a newer Companion against a database (or Redis/SQLite session store) containing tokens encrypted by an older Companion with a different encoding, or after changing COMPANION_SECRET so the old value no longer decrypts to a parseable structure.

Common situations: Upgrading Companion across major versions while keeping the old token store; changing or re-generating COMPANION_SECRET; restoring a database backup from an incompatible version.

Related errors


AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28). Data as JSON: /api/errors/9960609ee1d3356b. Report an issue: GitHub.