tursodatabase/turso · error · InvalidOperationException
Invalid sync HTTP header: {header.Name}
Error message
Invalid sync HTTP header: {header.Name} What it means
When building the HTTP request for sync I/O, headers returned by the native sync engine are added to the HttpRequestMessage; if a header cannot be added to the request or its content (even with TryAddWithoutValidation, which skips validation but still rejects malformed names/characters), HandleHttpCoreAsync throws InvalidOperationException naming the offending header.
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoSyncDatabase.cs:605
var baseUri = request.Url is null ? _remoteUri : NormalizeRemoteUri(new Uri(request.Url, UriKind.Absolute));
var requestUri = CombineUri(baseUri, request.Path);
ValidateAuthTransport(requestUri, _remoteUri, _options.AuthToken);
_lastTransportContext = new SyncTransportContext(
request.Method,
requestUri,
StatusCode: null);
using var message = new HttpRequestMessage(new HttpMethod(request.Method), requestUri);
if (request.Body.Length > 0)
message.Content = new ByteArrayContent(request.Body);
foreach (var header in request.Headers)
{
if (message.Headers.TryAddWithoutValidation(header.Name, header.Value))
continue;
message.Content ??= new ByteArrayContent([]);
if (!message.Content.Headers.TryAddWithoutValidation(header.Name, header.Value))
throw new InvalidOperationException($"Invalid sync HTTP header: {header.Name}");
}
if (!string.IsNullOrWhiteSpace(_options.AuthToken))
message.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _options.AuthToken);
using var response = await _httpClient
.SendAsync(message, HttpCompletionOption.ResponseHeadersRead, cancellationToken)
.ConfigureAwait(false);
_lastTransportContext = _lastTransportContext with
{
StatusCode = response.StatusCode,
};
TursoSyncBindings.SetIoStatus(item, (int)response.StatusCode);
await using var responseStream = await response.Content
.ReadAsStreamAsync(cancellationToken)
.ConfigureAwait(false);
var buffer = ArrayPool<byte>.Shared.Rent(IoBufferSize);
tryView on GitHub (pinned to 6c72522679)
Solutions
- Check the configured options (AuthToken and any custom headers) for illegal characters such as CR/LF or non-ASCII, and clean them.
- Upgrade Turso.Data so the header set emitted by the native sync core matches what HttpClient accepts.
- If you control the header source, rename/encode the header to a valid HTTP header name per RFC 7230.
Example fix
// before options.AuthToken = token + "\n"; // stray newline from config // after options.AuthToken = token.Trim();
Defensive patterns
Strategy: validation
Validate before calling
static void ValidateHttpHeader(string name, string value)
{
if (string.IsNullOrWhiteSpace(name) || name.Any(c => c < 33 || c > 126))
throw new ArgumentException($"Invalid sync HTTP header name: {name}");
if (value.Contains('\r') || value.Contains('\n'))
throw new ArgumentException("Header value contains line breaks.");
} Type guard
static bool IsValidHeader(string name, string value) =>
!string.IsNullOrWhiteSpace(name) &&
name.All(c => c > 32 && c < 127) &&
!value.Contains('\r') && !value.Contains('\n'); Prevention
- Trim AuthToken and any custom header values read from config/env (strip stray newlines).
- Use only RFC 7230-compliant header names in sync options.
- Validate header configuration at startup before first sync.
When it happens
Trigger: A sync HTTP exchange where the native layer supplies a header with an invalid name or characters (e.g. newlines, non-ASCII, forbidden header name conflicts) that both message.Headers.TryAddWithoutValidation and message.Content.Headers.TryAddWithoutValidation reject.
Common situations: Custom or unusual Auth Token / header configuration propagated from the native sync options; a native library version emitting headers outside what System.Net.Http allows; control characters accidentally included in configured values.
Related errors
- Automatic sync is not supported for embedded replica connect
- Turso sync operations cannot be reentered from the sync HTTP
- HTTP request failed: ${e instanceof Error ? e.message : Stri
- HTTP error! status: {(int)response.StatusCode}
- Empty pipeline response
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-08-31).
Data as JSON: /api/errors/610b970052c7f861.
Report an issue: GitHub.