tursodatabase/turso · error · InvalidOperationException
Encryption Cipher and Encryption Key are local database…
Error message
Encryption Cipher and Encryption Key are local database options and cannot be used with remote Turso URLs.
What it means
OpenRemote's third guard rejects local-only encryption options on remote URLs: Encryption Cipher and Encryption Key configure file-level encryption when opening a local database natively, and are meaningless over the wire, so supplying either (the check ORs a parsed cipher and any non-whitespace 'Encryption Key') with a remote Data Source throws InvalidOperationException at Open().
Solutions
- Remove 'Encryption Cipher' and 'Encryption Key' for remote connections — TLS secures the channel and the server handles encryption at rest
- Keep encryption options only on local file connection strings
- If you need a local encrypted database, use a file path Data Source where cipher plus key are honored
Example fix
// before var cs = "Data Source=libsql://db.turso.io;Auth Token=...;Encryption Cipher=aes256;Encryption Key=a1b2..."; // after var cs = "Data Source=libsql://db.turso.io;Auth Token=...";
Defensive patterns
Strategy: validation
Validate before calling
var opts = TursoConnectionOptions.Parse(cs);
if (opts.IsRemote && (opts.GetEncryptionCipher().HasValue || !string.IsNullOrWhiteSpace(opts["Encryption Key"])))
throw new InvalidOperationException(
"Remove encryption options: they only apply to local file databases."); Type guard
static bool EncryptionOptionsMatchMode(string cs)
{
var opts = TursoConnectionOptions.Parse(cs);
var hasEncryption = opts.GetEncryptionCipher().HasValue
|| !string.IsNullOrWhiteSpace(opts["Encryption Key"]);
return opts.IsRemote ? !hasEncryption : true;
} Try / catch
try { conn.Open(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Encryption Cipher and Encryption Key are local"))
{
// strip Encryption Cipher/Encryption Key from the remote connection string and retry
} Prevention
- Keep encrypted-database keywords only on local file connection strings
- Scope secrets-manager injections of encryption keys to local configs
- Rely on TLS plus server-side encryption for remote connections
When it happens
Trigger: Open() with 'Data Source=libsql://...;Encryption Cipher=aes256;Encryption Key=<hex>'; setting only 'Encryption Key' without a cipher on a remote URL; secrets managers injecting encryption keys into all connection strings uniformly.
Common situations: Security-hardened config templates applied to every environment; migrating an encrypted local database to Turso Cloud while keeping the keys in the string; copying between local and remote connection strings in appsettings.
Related errors
- Auth Token requires a remote Turso URL Data Source.
- Embedded replica connections are not supported yet by the…
- No remote transaction is active on this connection.
- Replica Path requires a remote Turso URL Data Source.
- Sync Interval requires a remote embedded replica connection.
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06).
Data as JSON: /api/errors/e97241a99cd0f797.
Report an issue: GitHub.
Appendix: source
Thrown at bindings/dotnet/src/Turso.Data/TursoConnection.cs:473
InvalidateRemoteSession();
}
}
private void OpenRemote()
{
if (_connectionOptions.IsReplica)
{
OpenReplica();
return;
}
if (_connectionOptions.SyncInterval > 0)
throw new NotSupportedException("Sync Interval requires an embedded replica connection.");
if (_connectionOptions.HasAdvancedReplicaOptions)
throw new NotSupportedException("Advanced sync options require an embedded replica connection.");
if (_connectionOptions.GetEncryptionCipher().HasValue || !string.IsNullOrWhiteSpace(_connectionOptions["Encryption Key"]))
throw new InvalidOperationException("Encryption Cipher and Encryption Key are local database options and cannot be used with remote Turso URLs.");
var handler = RemoteMessageHandlerFactory?.Invoke();
_remoteClient = handler is null
? new TursoRemoteClient(_connectionOptions.GetRemoteUri(), _connectionOptions.AuthToken)
: new TursoRemoteClient(
new HttpClient(handler),
_connectionOptions.GetRemoteUri(),
_connectionOptions.AuthToken,
disposeHttpClient: true);
}
private void OpenReplica()
{
var lease = TursoReplicaRegistry
.AcquireAsync(
CreateReplicaOptions(),
_connectionOptions.Pooling,
TimeSpan.FromSeconds(_connectionOptions.SyncInterval),View on GitHub (pinned to 6c72522679)