FlowiseAI/Flowise · error · Error

Credentials could not be decrypted.

Error message

Credentials could not be decrypted.

What it means

Thrown after decryption when the resulting decryptedDataStr cannot be JSON.parsed. This means the AES/Secrets-Manager decryption produced a string that is not a valid JSON object — typically because the encryption key is wrong, the payload is corrupted, or the stored value was never JSON to begin with.

Source

Thrown at packages/components/src/utils.ts:644

                decryptedDataStr = decryptedData.toString(enc.Utf8)
            }
        } catch (error) {
            console.error(error)
            throw new Error('Failed to decrypt credential data.')
        }
    } else {
        // Fallback to existing code
        const encryptKey = await getEncryptionKey()
        const decryptedData = AES.decrypt(encryptedData, encryptKey)
        decryptedDataStr = decryptedData.toString(enc.Utf8)
    }

    if (!decryptedDataStr) return {}
    try {
        return JSON.parse(decryptedDataStr)
    } catch (e) {
        console.error(e)
        throw new Error('Credentials could not be decrypted.')
    }
}

/**
 * Get credential data
 * @param {string} selectedCredentialId
 * @param {ICommonObject} options
 * @returns {Promise<ICommonObject>}
 */
export const getCredentialData = async (selectedCredentialId: string, options: ICommonObject): Promise<ICommonObject> => {
    const appDataSource = options.appDataSource as DataSource
    const databaseEntities = options.databaseEntities as IDatabaseEntity

    try {
        if (!selectedCredentialId) {
            return {}
        }

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Confirm FLOWISE_ENCRYPTION_KEY (or the key file at getEncryptionKeyPath()) is identical to the key used when the credential was saved.
  2. Re-create the affected credential through the Flowise UI so it is encrypted with the current key.
  3. Log decryptedDataStr (redacted) length to detect empty/garbage output — length 0 indicates a key mismatch.
  4. If migrating keys, write a one-time migration that decrypts with the old key and re-encrypts with the new one.

Example fix

// before
if (!decryptedDataStr) return {}
try {
  return JSON.parse(decryptedDataStr)
} catch (e) {
  console.error(e)
  throw new Error('Credentials could not be decrypted.')
}

// after — distinguish empty vs malformed and surface the parse error
if (!decryptedDataStr) return {}
try {
  return JSON.parse(decryptedDataStr)
} catch (e) {
  throw new Error(
    `Credentials could not be decrypted: decrypted payload is not valid JSON (len=${decryptedDataStr.length}). Likely an encryption-key mismatch.`,
    { cause: e }
  )
}
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeJson(s: string | undefined): boolean {
  if (!s) return false
  const t = s.trim()
  return t.startsWith('{') || t.startsWith('[')
}

Type guard

function isParsableCredentialJson(s: string): boolean {
  try { JSON.parse(s); return true } catch { return false }
}

Try / catch

try {
  return JSON.parse(decryptedDataStr)
} catch (e) {
  throw new Error(`Credentials could not be decrypted (len=${decryptedDataStr.length}). Likely key mismatch.`, { cause: e })
}

Prevention

When it happens

Trigger: decryptedData.toString(enc.Utf8) yields garbage (wrong key → crypto-js returns empty or mojibake); the encrypted blob was truncated/corrupted in the DB; the credential was originally stored as a plain string rather than JSON.stringify(obj); a DB migration altered the column charset and mangled the ciphertext.

Common situations: FLOWISE_ENCRYPTION_KEY changed without re-encrypting existing credentials; restoring a DB backup from an instance that used a different encryption key; crypto-js AES returning an empty WordArray that becomes '' (then toString gives '' and JSON.parse('') throws); SQLite/Postgres column encoding changes corrupting base64-style ciphertext.

Related errors


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/a5623ea047da0f10. Report an issue: GitHub.