{"record":{"id":"5aaf2be65b01feb9","repo":"tursodatabase/turso","slug":"remote-request-failed-with-http-int-response-sta","errorCode":null,"errorMessage":"Remote request failed with HTTP {(int)response.StatusCode} {response.ReasonPhrase}: {body}","messagePattern":"Remote request failed with HTTP (.+?) (.+?): (.+?)","errorType":"exception","errorClass":"TursoException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoRemoteClient.cs","lineNumber":156,"sourceCode":"\n        var json = JsonSerializer.Serialize(request, JsonOptions);\n        using var content = new StringContent(json, Encoding.UTF8, \"application/json\");\n        using var httpRequest = new HttpRequestMessage(HttpMethod.Post, _pipelineUri)\n        {\n            Content = content,\n        };\n\n        if (_authToken is not null)\n            httpRequest.Headers.Authorization = new AuthenticationHeaderValue(\"Bearer\", _authToken);\n\n        using var response = await _httpClient\n            .SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead, effectiveCancellationToken)\n            .ConfigureAwait(false);\n\n        var body = await response.Content.ReadAsStringAsync(effectiveCancellationToken).ConfigureAwait(false);\n        if (!response.IsSuccessStatusCode)\n        {\n            throw new TursoException(\n                $\"Remote request failed with HTTP {(int)response.StatusCode} {response.ReasonPhrase}: {body}\");\n        }\n\n        try\n        {\n            return JsonSerializer.Deserialize<RemotePipelineResponse>(body, JsonOptions)\n                   ?? throw new TursoException(\"Remote request returned an empty response.\");\n        }\n        catch (JsonException ex)\n        {\n            throw new TursoException($\"Unable to parse remote response: {ex.Message}\");\n        }\n    }\n\n    private static CancellationTokenSource? CreateTimeout(int commandTimeout, CancellationToken cancellationToken)\n    {\n        if (commandTimeout <= 0)\n            return null;","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/dotnet/src/Turso.Data/TursoRemoteClient.cs#L138-L174","documentation":"TursoRemoteClient.SendAsync wraps every non-success HTTP response in a TursoException that includes the status code, reason phrase, and the full response body. This is the single funnel for all remote-side failures: authentication problems (401/403), unknown database URLs (404), rate limiting (429), and server errors (5xx). Reading the numeric code out of the message is the way to branch on the failure class.","triggerScenarios":"Any remote pipeline request where the server returns non-2xx: an expired or wrong Auth Token (401), a token without access to the database (403), a Data Source URL pointing at a nonexistent database (404), plan limits or burst traffic (429), or Turso Cloud incidents (5xx). Also seen when a proxy or captive portal answers with an unexpected status and HTML body.","commonSituations":"Rotated/short-lived database tokens not refreshed in long-running services; wrong database URL copied between projects; CI hitting rate limits during parallel test runs; corporate proxies intercepting requests; scheduled token expiry caught only in production.","solutions":["For 401/403: verify the Auth Token is valid and scoped to the database in the Data Source URL (re-issue with the Turso CLI).","For 404: check the Data Source host matches the database URL shown in the Turso dashboard (watch for typos and stale URLs).","For 429/5xx: retry with exponential backoff and jitter; these classes are transient.","For proxy interference: ensure egress to *.turso.io is direct and the Authorization header survives."],"exampleFix":"// before\nvar results = await client.ExecuteBatchAsync(batch, 30, true, false, ct);\n\n// after\ncatch (TursoException ex) when (ex.Message.StartsWith(\"Remote request failed with HTTP 4\"))\n{\n    // non-retryable: token/URL/config problem — surface it\n    logger.LogError(ex, \"Remote Turso call rejected\");\n    throw;\n}","handlingStrategy":"retry","validationCode":"// Pre-flight sanity (cheap, catches most 401/404 before first query):\nif (string.IsNullOrWhiteSpace(options.AuthToken)) throw new ConfigurationException(\"Turso Auth Token missing\");\nif (!options.IsRemote) throw new ConfigurationException(\"Data Source must be a remote URL\");","typeGuard":"static int? ExtractHttpStatus(TursoException ex)\n{\n    const string prefix = \"Remote request failed with HTTP \";\n    return ex.Message.StartsWith(prefix) && int.TryParse(ex.Message.AsSpan(prefix.Length, 3), out var code)\n        ? code : null;\n}","tryCatchPattern":"catch (TursoException ex) when (ExtractHttpStatus(ex) is 408 or 429 or >= 500)\n{\n    await Task.Delay(backoff.Next(), ct); // exponential backoff + jitter, then retry\n}\ncatch (TursoException ex) when (ExtractHttpStatus(ex) is 401 or 403)\n{\n    logger.LogError(ex, \"Turso auth failed — refresh the database token\");\n    throw;\n}","preventionTips":["Refresh short-lived database tokens on a schedule before expiry, not on failure.","Wrap remote calls in retry-with-backoff for 429/5xx only; never retry 4xx auth/config errors.","Log the status code (parsed from the message) plus request ID so support tickets are actionable."],"tags":["csharp","dotnet","http","remote-client","auth-token","network"],"backgroundTag":"http-error-response","analyzedSha":"6c7252267988c76e632af00a671e4b9788dfae13","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}