FlowiseAI/Flowise · error · Error

Failed to decrypt credential data.

Error message

Failed to decrypt credential data.

What it means

Catch-all thrown by the AWS Secrets Manager branch of decryptCredentialData. It wraps any exception raised during GetSecretValueCommand.send(), JSON.parse of the secret, or AES.decrypt of a non-FlowiseCredential_ payload. The original error is console.error'd but not re-thrown verbatim, so the real cause is hidden behind this generic message.

Solutions

  1. Read the console.error output in the logs to find the underlying cause (AccessDenied, DecryptionFailure, Throttling, etc.).
  2. If AES path: confirm FLOWISE_ENCRYPTION_KEY / encryption key file matches the key used when credentials were originally encrypted.
  3. If AWS path: verify IAM permissions (secretsmanager:GetSecretValue + kms:Decrypt) and that the secret's region matches the client config.
  4. Re-encrypt credentials via the Flowise credential UI after rotating keys so they align with the current encryption key.
  5. If the secret payload isn't JSON, re-store it as a valid JSON object.

Example fix

// before — original error swallowed
} catch (error) {
  console.error(error)
  throw new Error('Failed to decrypt credential data.')
}

// after — preserve the original error as cause
} catch (error) {
  console.error(error)
  throw new Error(`Failed to decrypt credential data: ${error instanceof Error ? error.message : String(error)}`, { cause: error })
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify AWS client config and key presence before decrypting
function assertSecretsManagerReady(client: SecretsManagerClient | undefined) {
  if (!client) throw new Error('Secrets Manager client is not initialised')
}

Type guard

function isAwsSdkError(e: unknown): e is { name: string; message: string; Code?: string } {
  return typeof e === 'object' && e !== null && 'name' in e
}

Try / catch

try {
  // ... decryption logic
} catch (error) {
  console.error('decryptCredentialData failure:', error)
  throw new Error(`Failed to decrypt credential data: ${error instanceof Error ? error.message : String(error)}`, { cause: error })
}

Prevention

When it happens

Trigger: AWS SDK throws (throttling, network, AccessDeniedException, KMS key disabled); JSON.parse fails because the stored SecretString is not valid JSON; AES.decrypt throws because the encryption key mismatched the payload (e.g. FLOWISE_ENCRYPTION_KEY changed); secretsManagerClient.send rejects due to an expired AWS session token.

Common situations: Rotating FLOWISE_ENCRYPTION_KEY after credentials were encrypted with the old key; AWS temporary credentials expiring mid-session; KMS key used to encrypt the secret was scheduled for deletion; Secrets Manager service throttling under load; region misconfiguration where the client targets a different region than the secret.

Related errors


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

Appendix: source

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

        try {
            if (encryptedData.startsWith('FlowiseCredential_')) {
                const command = new GetSecretValueCommand({ SecretId: encryptedData })
                const response = await secretsManagerClient.send(command)

                if (response.SecretString) {
                    const secretObj = JSON.parse(response.SecretString)
                    decryptedDataStr = JSON.stringify(secretObj)
                } else {
                    throw new Error('Failed to retrieve secret value.')
                }
            } else {
                const encryptKey = await getEncryptionKey()
                const decryptedData = AES.decrypt(encryptedData, encryptKey)
                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.')
    }
}

/**

View on GitHub (pinned to abe4a8601a)