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);
        try

View on GitHub (pinned to 6c72522679)

Solutions

  1. Check the configured options (AuthToken and any custom headers) for illegal characters such as CR/LF or non-ASCII, and clean them.
  2. Upgrade Turso.Data so the header set emitted by the native sync core matches what HttpClient accepts.
  3. 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

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


AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-08-31). Data as JSON: /api/errors/610b970052c7f861. Report an issue: GitHub.