{"record":{"id":"84d1c327687c1c47","repo":"tursodatabase/turso","slug":"the-sync-remote-url-must-use-turso-libsql-http","errorCode":null,"errorMessage":"The sync remote URL must use turso, libsql, HTTP, or HTTPS.","messagePattern":"The sync remote URL must use turso, libsql, HTTP, or HTTPS\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoSyncDatabaseOptions.cs","lineNumber":139,"sourceCode":"    public string? ExperimentalFeatures { get; init; }\n\n    internal Uri GetNormalizedRemoteUri()\n    {\n        if (!RemoteUri.IsAbsoluteUri)\n            throw new ArgumentException(\"The sync remote URL must be absolute.\", nameof(RemoteUri));\n        if (!string.IsNullOrEmpty(RemoteUri.Query) || !string.IsNullOrEmpty(RemoteUri.Fragment))\n            throw new ArgumentException(\"The sync remote URL must not include a query string or fragment.\", nameof(RemoteUri));\n        if (!string.IsNullOrEmpty(RemoteUri.UserInfo))\n            throw new ArgumentException(\"Use AuthToken instead of embedding credentials in the sync URL.\", nameof(RemoteUri));\n        if (string.IsNullOrEmpty(RemoteUri.Host))\n            throw new ArgumentException(\"The sync remote URL must include a host.\", nameof(RemoteUri));\n\n        var scheme = RemoteUri.Scheme.ToLowerInvariant() switch\n        {\n            \"turso\" or \"libsql\" => Uri.UriSchemeHttps,\n            \"http\" => Uri.UriSchemeHttp,\n            \"https\" => Uri.UriSchemeHttps,\n            _ => throw new ArgumentException(\n                \"The sync remote URL must use turso, libsql, HTTP, or HTTPS.\",\n                nameof(RemoteUri)),\n        };\n        var builder = new UriBuilder(RemoteUri)\n        {\n            Scheme = scheme,\n            Port = RemoteUri.IsDefaultPort ? -1 : RemoteUri.Port,\n            UserName = string.Empty,\n            Password = string.Empty,\n        };\n        return builder.Uri;\n    }\n\n    internal void Validate()\n    {\n        ArgumentException.ThrowIfNullOrWhiteSpace(Path);\n        ArgumentException.ThrowIfNullOrWhiteSpace(ClientName);\n","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/tursodatabase/turso/blob/c1e59287258d99b309e362a63f48822256e2f65f/bindings/dotnet/src/Turso.Data/TursoSyncDatabaseOptions.cs#L121-L157","documentation":"GetNormalizedRemoteUri only accepts schemes turso, libsql, http, and https; turso and libsql are normalized to https. Any other scheme (ftp, ws, file, wss, tcp, etc.) is rejected because the sync protocol runs over HTTP/HTTPS.","triggerScenarios":"Constructing TursoSyncDatabaseOptions with a RemoteUri whose lowercase scheme is not one of turso/libsql/http/https — e.g. new Uri(\"wss://host/db\"), \"ftp://...\", or a scheme typo like \"htps://\" (which usually fails earlier as a relative URI) — thrown at TursoSyncDatabaseOptions.cs:139-141.","commonSituations":"Reusing WebSocket URLs from other libsql clients (ws/wss), copying database URLs from non-Turso services, editing config and mangling the scheme, using httpx/file URIs from local-only setups.","solutions":["Use https:// (or http:// for plain HTTP, or turso:// / libsql:// which map to HTTPS) as the URL scheme.","Convert ws/wss URLs to http/https equivalents.","Verify the URL string in configuration starts with an accepted scheme and has no typos."],"exampleFix":"// before\nvar opts = new TursoSyncDatabaseOptions(path, new Uri(\"wss://mydb.turso.io\"));\n// after\nvar opts = new TursoSyncDatabaseOptions(path, new Uri(\"https://mydb.turso.io\"));","handlingStrategy":"validation","validationCode":"static readonly string[] AllowedSchemes = { \"turso\", \"libsql\", \"http\", \"https\" };\nstatic void EnsureAllowedScheme(Uri remoteUri)\n{\n    if (!AllowedSchemes.Contains(remoteUri.Scheme.ToLowerInvariant()))\n        throw new ArgumentException($\"Scheme '{remoteUri.Scheme}' not allowed; use turso, libsql, http, or https.\");\n}","typeGuard":"static bool HasSyncScheme(Uri u) => u.IsAbsoluteUri && u.Scheme.ToLowerInvariant() is \"turso\" or \"libsql\" or \"http\" or \"https\";","tryCatchPattern":"try { var db = new TursoSyncDatabase(opts); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"must use turso, libsql, HTTP, or HTTPS\"))\n{\n    // rewrite scheme (e.g. wss -> https) and retry\n}","preventionTips":["Standardize on https:// URLs for all environments; reserve turso:// for Turso connection strings.","Convert ws/wss URLs from other libsql clients to http/https.","Store URLs with their scheme in config and validate with Uri.TryCreate plus a scheme allow-list."],"tags":["dotnet","sync","url-validation","scheme","argument-exception"],"backgroundTag":"invalid-sync-url","analyzedSha":"c1e59287258d99b309e362a63f48822256e2f65f","analyzedAt":"2026-08-31T11:17:35.598Z","contentChangedAt":"2026-08-31T11:17:35.598Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}