tursodatabase/turso · error · TursoServerlessException
No cursor response received
Error message
No cursor response received
What it means
On the NDJSON /v3/cursor protocol, the first non-empty line of the 2xx response must deserialize to HranaCursorResponse; remaining lines stream as entries. If the response stream ends with no non-empty line at all, this TursoServerlessException is thrown — the HTTP layer succeeded but delivered no data to parse.
Source
Thrown at bindings/dotnet/src/Turso.Serverless.Client/HranaHttp.cs:92
}
var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
reader = new StreamReader(stream, Encoding.UTF8);
// The first non-empty line is the cursor response; the rest are cursor entries.
HranaCursorResponse? cursorResponse = null;
while (await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false) is { } line)
{
if (line.Trim() is not ("" or null) and var trimmed)
{
cursorResponse = JsonSerializer.Deserialize<HranaCursorResponse>(trimmed, JsonOptions);
break;
}
}
if (cursorResponse is null)
{
throw new TursoServerlessException("No cursor response received");
}
var entries = ReadEntriesAsync(response, reader, cancellationToken);
response = null; // Ownership transferred to the entry enumerator.
reader = null;
return (cursorResponse, entries);
}
finally
{
reader?.Dispose();
response?.Dispose();
httpRequest.Dispose();
}
}
private static async IAsyncEnumerable<HranaCursorEntry> ReadEntriesAsync(
HttpResponseMessage response,
StreamReader reader,View on GitHub (pinned to 244cde92a7)
Solutions
- Retry the cursor request: an empty stream after successful headers is usually a transient network/infrastructure fault.
- Ensure the network path supports unbuffered streaming (test with curl -N against /v3/cursor).
- Disable response buffering for this route in your proxy/gateway (nginx proxy_buffering off and equivalents).
- Lengthen or remove first-byte read timeouts if intermediaries cut slow-starting streams.
Defensive patterns
Strategy: retry
Validate before calling
// probe that the cursor endpoint streams data before building on it
using var resp = await httpClient.SendAsync(probeRequest, HttpCompletionOption.ResponseHeadersRead);
using var stream = await resp.Content.ReadAsStreamAsync();
using var sr = new StreamReader(stream);
if (await sr.ReadLineAsync() is null) throw new InvalidOperationException("Cursor endpoint returned an empty stream"); Try / catch
catch (TursoServerlessException ex) when (ex.Message == "No cursor response received" && attempt < 3)
{
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
continue; // empty stream after 2xx is almost always transient
} Prevention
- Disable proxy buffering for streaming routes (e.g. nginx proxy_buffering off).
- Set generous first-byte timeouts; streams may start slowly.
- Retry empty streams once or twice before escalating; persistent emptiness means an infrastructure fault, not a query problem.
When it happens
Trigger: A 200 response with an entirely empty body; a connection that delivers headers then closes (dropped long-lived/streaming connection); buffering proxies that terminate or truncate streaming responses.
Common situations: Reverse proxies or corporate networks closing streaming connections; intermittent mobile/cloud networking dropping the body; server-side incident producing empty streams; timeouts between headers and first byte.
Related errors
- HTTP error! status: {(int)response.StatusCode}
- Empty pipeline response
- Only finite numbers (not Infinity or NaN) can be passed as a
- Unexpected token for last_insert_rowid: {reader.TokenType}
- Describe execution failed
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/7c8b2223a8feac13.
Report an issue: GitHub.