tursodatabase/turso · error · NotSupportedException
Isolation level {isolationLevel} is not supported.
Error message
Isolation level {isolationLevel} is not supported. What it means
TursoTransaction.NormalizeIsolationLevel maps several System.Transactions IsolationLevel values onto what SQLite/Turso actually supports. Most levels are coerced to Serializable, ReadUncommitted is allowed, and anything else (e.g. Chaos, Snapshot) has no mapping, so NotSupportedException is thrown.
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoTransaction.cs:144
_completed = true;
}
private void ThrowIfCompleted()
{
if (_completed)
throw new InvalidOperationException("This transaction has already completed.");
}
private static IsolationLevel NormalizeIsolationLevel(IsolationLevel isolationLevel)
{
return isolationLevel switch
{
IsolationLevel.Unspecified => IsolationLevel.Serializable,
IsolationLevel.Serializable => IsolationLevel.Serializable,
IsolationLevel.ReadCommitted => IsolationLevel.Serializable,
IsolationLevel.RepeatableRead => IsolationLevel.Serializable,
IsolationLevel.ReadUncommitted => IsolationLevel.ReadUncommitted,
_ => throw new NotSupportedException($"Isolation level {isolationLevel} is not supported.")
};
}
}
View on GitHub (pinned to 6c72522679)
Solutions
- Use IsolationLevel.Serializable (the default and fully supported) or ReadUncommitted.
- Remove Snapshot/Chaos settings from TransactionScope or connection BeginTransaction calls.
- Wrap the BeginTransaction call in a mapping function that converts unsupported levels to Serializable before calling the provider.
- If you truly need Snapshot semantics, restructure the workload to rely on explicit transactions instead.
Example fix
// before using var tx = conn.BeginTransaction(IsolationLevel.Snapshot); // after var level = iso == IsolationLevel.Snapshot ? IsolationLevel.Serializable : iso; using var tx = conn.BeginTransaction(level);
Defensive patterns
Strategy: validation
Validate before calling
// Map any unsupported level before calling the provider
IsolationLevel Normalize(IsolationLevel iso) =>
iso is IsolationLevel.Serializable or IsolationLevel.ReadCommitted or
IsolationLevel.RepeatableRead or IsolationLevel.Unspecified
? IsolationLevel.Serializable
: iso == IsolationLevel.ReadUncommitted ? IsolationLevel.ReadUncommitted
: throw new NotSupportedException($"{iso} not supported by Turso"); Try / catch
try { tx = conn.BeginTransaction(iso); }
catch (NotSupportedException ex) when (ex.Message.Contains("Isolation level"))
{
tx = conn.BeginTransaction(IsolationLevel.Serializable); // safe fallback
} Prevention
- Always use IsolationLevel.Serializable (default) unless you specifically need ReadUncommitted.
- Don't copy SQL Server TransactionScope settings (Snapshot) into SQLite-family code.
- Keep a single mapping helper for isolation levels used across the app.
When it happens
Trigger: Beginning a TursoTransaction with BeginTransaction(IsolationLevel.Chaos) or IsolationLevel.Snapshot, or setting an unsupported level via System.Transactions.TransactionScope options that propagate into the ADO.NET provider.
Common situations: Porting code written for SQL Server that uses Snapshot isolation; TransactionScope configured with a non-SQLite isolation level; generic ORM code that passes through a configurable isolation level enum.
Related errors
- SQLite facade batches are available only for direct remote o
- A transaction is already active on this connection.
- No remote transaction is active on this connection.
- Embedded replica sync is not supported yet by the .NET provi
- Embedded replica connections are not supported yet by the .N
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06).
Data as JSON: /api/errors/479d1a9cc3fd7a5b.
Report an issue: GitHub.