tursodatabase/turso · error · TursoServerlessException
Empty pipeline response
Error message
Empty pipeline response
What it means
After a successful (2xx) pipeline response, the body is deserialized into HranaPipelineResponse; a null result throws TursoServerlessException with this message. A null only arises when the body is empty/whitespace or the literal JSON null — a healthy pipeline endpoint always returns an object with a results array.
Source
Thrown at bindings/dotnet/src/Turso.Serverless.Client/HranaHttp.cs:37
internal static async Task<HranaPipelineResponse> ExecutePipelineAsync(
HttpClient httpClient,
string baseUrl,
string? authToken,
string? remoteEncryptionKey,
HranaPipelineRequest request,
CancellationToken cancellationToken)
{
using var httpRequest = CreateRequest($"{baseUrl}/v3/pipeline", authToken, remoteEncryptionKey, request);
using var response = await httpClient.SendAsync(httpRequest, HttpCompletionOption.ResponseContentRead, cancellationToken).ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
{
throw new TursoServerlessException($"HTTP error! status: {(int)response.StatusCode}");
}
var body = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
return JsonSerializer.Deserialize<HranaPipelineResponse>(body, JsonOptions)
?? throw new TursoServerlessException("Empty pipeline response");
}
internal static async Task<(HranaCursorResponse Response, IAsyncEnumerable<HranaCursorEntry> Entries)> ExecuteCursorAsync(
HttpClient httpClient,
string baseUrl,
string? authToken,
string? remoteEncryptionKey,
HranaCursorRequest request,
CancellationToken cancellationToken)
{
var httpRequest = CreateRequest($"{baseUrl}/v3/cursor", authToken, remoteEncryptionKey, request);
HttpResponseMessage? response = null;
StreamReader? reader = null;
try
{
response = await httpClient.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
View on GitHub (pinned to 244cde92a7)
Solutions
- Confirm the baseUrl actually targets the database's HTTP endpoint (test the same pipeline with curl).
- Bypass or configure intermediaries (proxy, gateway) that may strip bodies; check their logs.
- Retry once — empty 200s from infrastructure glitches are usually transient.
- If reproducible only through your stack, capture the raw response (status, headers, length) to pinpoint which hop emptied it.
Defensive patterns
Strategy: retry
Validate before calling
// verify the endpoint serves the pipeline protocol before relying on it
using var probe = new HttpClient();
var resp = await probe.PostAsync(url + "/v3/pipeline", new StringContent("{\"requests\":[]}", Encoding.UTF8, "application/json"));
var body = await resp.Content.ReadAsStringAsync();
if (string.IsNullOrWhiteSpace(body)) throw new InvalidOperationException("Endpoint returned an empty body; check baseUrl/proxy"); Try / catch
catch (TursoServerlessException ex) when (ex.Message == "Empty pipeline response")
{
if (attempt < 2) { await Task.Delay(backoff); continue; } // transient empty 200
throw; // persistent: wrong endpoint or body-stripping intermediary
} Prevention
- Point baseUrl at the database HTTP endpoint, never a dashboard/static host.
- Disable body-rewriting in proxies on this route.
- Monitor response content-length in integration checks to catch emptied bodies early.
When it happens
Trigger: A 200 response with an empty body: misrouted baseUrl (static host, wrong port), a proxy or gateway that swallowed the body, health-check responses, or the literal string null from a misbehaving intermediary.
Common situations: Corporate proxies or API gateways rewriting responses; baseUrl pointing at a dashboard/static domain instead of the database endpoint; rare server-side incidents returning empty 200s.
Related errors
- HTTP error! status: {(int)response.StatusCode}
- No cursor response received
- Unexpected token for last_insert_rowid: {reader.TokenType}
- Unable to parse remote response: {ex.Message}
- Extensions array cannot be null.
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/37d9e67b833ba8a4.
Report an issue: GitHub.