tursodatabase/turso · error · SqliteException
1
1
Error message
SQLite Error {errorCode}: 'no such vfs: {vfs}'. What it means
Thrown while normalizing the connection string when the 'Vfs' keyword is non-empty but not one of the two VFS names this managed binding accepts: 'win32-longpath' or 'unix-dotfile' (see IsSupportedVfs in SqliteConnection.cs:789). The message mirrors SQLite's native 'no such vfs' error with SQLite error code 1 (SQLITE_ERROR). Unlike Microsoft.Data.Sqlite, which forwards the name to the native library where many VFS modules exist, this binding validates the name itself and fails before any database is opened.
Solutions
- Remove the 'Vfs=' entry from the connection string; it is optional and the binding uses its own virtual file system.
- If you need the behavior it provided, use one of the two accepted values: Vfs=win32-longpath (Windows long paths) or Vfs=unix-dotfile (dot-file locking).
- Search your config files, appsettings, and ORM setup (e.g. UseSqlite("...")) for 'Vfs=' and delete or correct every occurrence.
Example fix
// before
var conn = new SqliteConnection("Data Source=app.db;Vfs=unix-excl");
// after
var conn = new SqliteConnection("Data Source=app.db");
// or, if dot-file locking is specifically wanted:
var conn = new SqliteConnection("Data Source=app.db;Vfs=unix-dotfile"); Defensive patterns
Strategy: validation
Validate before calling
static readonly string[] SupportedVfs = { "win32-longpath", "unix-dotfile" };
static bool VfsOk(string? vfs)
=> string.IsNullOrEmpty(vfs)
|| SupportedVfs.Contains(vfs, StringComparer.OrdinalIgnoreCase);
if (!VfsOk(config.Vfs)) throw new ConfigException($"Unsupported Vfs '{config.Vfs}'."); Try / catch
try { conn.Open(); }
catch (SqliteException ex) when (ex.SqliteErrorCode == 1 && ex.Message.Contains("no such vfs"))
{ /* strip Vfs from the connection string and rebuild */ } Prevention
- Do not set Vfs unless you specifically need win32-longpath or unix-dotfile behavior.
- Keep connection strings in one config source and review them when switching SQLite provider packages.
When it happens
Trigger: Constructing SqliteConnection with a connection string containing 'Vfs=unix-excl' (or 'unix', 'win32', 'unix-none'), or setting builder.Vfs = "unix-excl". Anything except 'win32-longpath' and 'unix-dotfile' (case-insensitive) throws from NormalizeDataSource.
Common situations: Copying a connection string written for Microsoft.Data.Sqlite or System.Data.SQLite whose bundled native SQLite supports more VFS names; attempting long-path or dot-file locking workarounds copied from SQLite docs; migrating an app to the Turso managed binding without pruning unsupported options.
Related errors
- 14
- Auth Token requires a remote Turso URL Data Source.
- Cannot convert to .
- Column name is ambiguous between and .
- Column was not found.
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-08-20).
Data as JSON: /api/errors/d5fdeffdf5164900.
Report an issue: GitHub.
Appendix: source
Thrown at bindings/dotnet/src/Turso.Data.Sqlite/SqliteConnection.cs:1073
return true;
}
private static void SkipSqlWhitespace(string sql, ref int index)
{
while (index < sql.Length && char.IsWhiteSpace(sql[index]))
index++;
}
private static bool IsSqlIdentifierPart(char value)
=> char.IsLetterOrDigit(value) || value == '_' || value == '$';
private static string NormalizeDataSource(SqliteConnectionStringBuilder options)
{
var dataSource = options.DataSource;
if (string.IsNullOrEmpty(dataSource))
return ":memory:";
if (options.Vfs is { Length: > 0 } vfs && !IsSupportedVfs(vfs))
throw new SqliteException(Properties.Resources.SqliteNativeError(SQLITE_ERROR, "no such vfs: " + vfs), SQLITE_ERROR);
if (dataSource == ":memory:")
return dataSource;
if (options.Mode == SqliteOpenMode.Memory)
return options.Cache == SqliteCacheMode.Shared && dataSource.Length > 0
? GetSharedMemoryFile(dataSource)
: ":memory:";
if (dataSource.StartsWith("file:", StringComparison.OrdinalIgnoreCase))
return NormalizeUriDataSource(dataSource);
const string dataDirectory = "|DataDirectory|";
if (dataSource.StartsWith(dataDirectory, StringComparison.OrdinalIgnoreCase))
{
var baseDirectory = AppDomain.CurrentDomain.GetData("DataDirectory") as string
?? AppContext.BaseDirectory;
dataSource = Path.Combine(baseDirectory, dataSource[dataDirectory.Length..].TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
}
var filename = Path.IsPathRooted(dataSource)View on GitHub (pinned to 6c72522679)