tursodatabase/turso · error · InvalidOperationException
Encryption is not supported by {libraryName}.
Error message
Encryption is not supported by {libraryName}. What it means
Open() throws InvalidOperationException when the connection string contains a non-empty Password, because the Turso SQLite-compatible provider (backed by the e_sqlite3 native library) is built without encryption support (no SQLITE_HAS_CODEC/SEE). The check happens before any file is opened, so no database is created or touched. This intentionally fails fast instead of silently ignoring the password and writing an unencrypted file.
Source
Thrown at bindings/dotnet/src/Turso.Data.Sqlite/SqliteConnection.cs:95
{
get => _readUncommitted;
set => _readUncommitted = value;
}
// The SQLite version Turso tracks (SQLITE_VERSION in core/dialect/sqlite.rs).
public override string ServerVersion => "3.50.4";
public override ConnectionState State => _database is null ? ConnectionState.Closed : ConnectionState.Open;
protected override DbProviderFactory DbProviderFactory => SqliteFactory.Instance;
public override void Open()
{
ObjectDisposedException.ThrowIf(_disposed, this);
if (_database is not null)
throw new InvalidOperationException("The connection is already open.");
if (!string.IsNullOrEmpty(_connectionOptions.Password))
throw new InvalidOperationException(Properties.Resources.EncryptionNotSupported("e_sqlite3"));
var originalState = State;
var filename = NormalizeDataSource(_connectionOptions);
var readOnly = _connectionOptions.Mode == SqliteOpenMode.ReadOnly;
var sharedMemoryPath = IsSharedMemory(_connectionOptions) ? RegisterSharedMemoryFile(filename) : null;
try
{
_database = TursoBindings.OpenDatabase(filename);
_dataSource = filename;
_readOnly = readOnly;
_sharedMemoryPath = sharedMemoryPath;
ApplyExtensionSettings();
ApplyConnectionOptions();
RegisterScalarFunctions();
RegisterAggregateFunctions();
RegisterCollations();
LoadPendingExtensions();
OnStateChange(new StateChangeEventArgs(originalState, State));View on GitHub (pinned to 244cde92a7)
Solutions
- Remove the Password entry from the connection string (it is never honored by this provider).
- If data-at-rest encryption is required, use an approach outside this provider: full-disk/OS file encryption, EFS/LUKS, or a provider that ships SQLCipher and convert the file there.
- Encrypt/decrypt sensitive columns at the application layer (e.g. AES via a UDF or in code) instead of whole-file encryption.
Example fix
// before
var cs = new SqliteConnectionStringBuilder { DataSource = "enc.db", Password = "secret" };
using var conn = new SqliteConnection(cs.ToString());
conn.Open(); // throws: Encryption is not supported by e_sqlite3
// after
var cs = new SqliteConnectionStringBuilder { DataSource = "plain.db" };
using var conn = new SqliteConnection(cs.ToString());
conn.Open(); // encrypt at the application layer if needed Defensive patterns
Strategy: validation
Validate before calling
static string StripUnsupportedPassword(string cs)
{
var b = new SqliteConnectionStringBuilder(cs);
if (b.TryGetValue("Password", out var pwd) && !string.IsNullOrEmpty(pwd?.ToString()))
{
b.Remove("Password");
// decide policy here: fail loudly, or proceed unencrypted knowingly
}
return b.ConnectionString;
}
// usage: new SqliteConnection(StripUnsupportedPassword(cs)) Try / catch
null
Prevention
- Do not share one config template with a Password key across providers.
- Document whole-file encryption as unsupported with this provider; choose app-layer or OS-level encryption deliberately.
- Fail configuration validation at startup if a Password appears in a Turso connection string, rather than discovering it at first Open.
When it happens
Trigger: 'Data Source=enc.db;Password=secret' in the connection string; connection strings copied from SQLCipher, System.Data.SQLite (with codec), or SEE-based deployments; shared config files that carry a Password key for all providers.
Common situations: Migrating an encrypted database from another SQLite distribution and assuming the Turso provider reads the same option; multi-provider config where a global Password property is applied to every connection string; leftover Password keys from an earlier stack.
Related errors
- The connection string can only be set when the connection is
- Missing parameter values for {parameters}.
- Parameter name {parameterName} is ambiguous.
- Cannot access a disposed object. Object name: 'AggregateInv
- CollationRegistration
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/bcd8648c3ef481e8.
Report an issue: GitHub.