tursodatabase/turso · error · NotSupportedException

Custom extension entry points are not yet supported by the T

Error message

Custom extension entry points are not yet supported by the Turso SQLite-compatible provider.

What it means

LoadExtension(file, proc) throws NotSupportedException whenever the proc argument is non-null: the Turso provider cannot load extensions through a custom named entry point, only through the default one an extension exports (sqlite3_extension_init / sqlite3_<name>_init). The check happens before any file is touched, so the extension is never loaded. Passing proc: null (or omitting it) takes the normal path (immediate or pending until open).

Source

Thrown at bindings/dotnet/src/Turso.Data.Sqlite/SqliteConnection.cs:465

    public virtual void CreateAggregate<TAccumulate, TResult>(string name, TAccumulate seed, Func<TAccumulate, object?[], TAccumulate>? func, Func<TAccumulate, TResult>? resultSelector, bool isDeterministic = false)
    {
        RegisterAggregateFunction(name, -1, isDeterministic, seed, func is null ? null : (accumulator, args) => InvokeSeededAggregateStep(func, accumulator, args), accumulator => InvokeResultSelector(resultSelector!, accumulator));
    }

    public virtual void EnableExtensions(bool enable = true)
    {
        ThrowIfManagedLocalOnly(nameof(EnableExtensions));
        _extensionsEnabled = enable;
        if (_database is not null)
            TursoBindings.EnableLoadExtension(DatabaseHandle, enable);
    }

    public virtual void LoadExtension(string file, string? proc = null)
    {
        ThrowIfManagedLocalOnly(nameof(LoadExtension));
        ArgumentNullException.ThrowIfNull(file);
        if (proc is not null)
            throw new NotSupportedException("Custom extension entry points are not yet supported by the Turso SQLite-compatible provider.");

        if (_database is null)
        {
            _pendingExtensions.Add((file, proc));
            return;
        }

        LoadExtensionCore(file, proc);
    }

    public virtual void BackupDatabase(SqliteConnection destination)
        => BackupDatabase(destination, "main", "main");

    public virtual void BackupDatabase(SqliteConnection destination, string destinationName, string sourceName)
    {
        ThrowIfManagedLocalOnly(nameof(BackupDatabase));
        if (_database is null)
            throw new InvalidOperationException(Properties.Resources.CallRequiresOpenConnection("BackupDatabase"));

View on GitHub (pinned to 6c72522679)

Solutions

  1. Omit the proc argument so the default entry point is used: conn.LoadExtension("path/to/ext").
  2. If the extension exports a truly non-default name, rebuild/relink it to export sqlite3_extension_init (or sqlite3_<name>_init) so the default resolution finds it.
  3. Enable extensions first with conn.EnableExtensions(true) if loading has not been enabled yet.

Example fix

// before
conn.EnableExtensions(true);
conn.LoadExtension("uuid", "sqlite3_uuid_init"); // throws: custom entry points not supported

// after
conn.EnableExtensions(true);
conn.LoadExtension("uuid"); // default entry point
Defensive patterns

Strategy: validation

Validate before calling

static void LoadExtensionDefaultEntryPoint(SqliteConnection conn, string file)
{
    conn.EnableExtensions(true);
    conn.LoadExtension(file); // never pass proc; default entry point only
}

Try / catch

null

Prevention

When it happens

Trigger: Porting code from Microsoft.Data.Sqlite/System.Data.SQLite that loads an extension with an explicit entry point, e.g. LoadExtension("uuid", "sqlite3_uuid_init"); loading extensions whose docs instruct a custom proc because their export is non-standard; generic extension loaders that always pass an entryPoint value.

Common situations: Migrating an app that used spellfix/uuid/crypto extensions with named entry points, build scripts shared across providers that pass proc uniformly, and third-party extension docs that assume the official SQLite API contract.

Related errors


AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06). Data as JSON: /api/errors/f487e14fe355015b. Report an issue: GitHub.