tursodatabase/turso · error · Error

HTTP request failed: ${e instanceof Error ? e.message : Stri

Error message

HTTP request failed: ${e instanceof Error ? e.message : String(e)}. URL: ${fullUrl}, Method: ${request.method}, Body size: ${request.body ? request.body.byteLength : 0} bytes

What it means

processHttpRequest() executes sync IO with fetch(); if fetch itself throws (network-level failure), the catch logs structured details via console.error ('[Turso HTTP] Request failed:') and rethrows this wrapper including the underlying message, URL, method, and body size. Note that HTTP error statuses are NOT this error — response.status is delivered to the engine via item.setStatus(); this throw means the request never completed.

Source

Thrown at bindings/react-native/src/internal/ioProcessor.ts:217

  let response;
  try {
    response = await fetch(fullUrl, options);
  } catch (e) {
    // Detailed error logging
    const errorDetails = {
      url: fullUrl,
      method: request.method,
      hasBody: !!request.body,
      bodySize: request.body ? request.body.byteLength : 0,
      bodyType: request.body ? Object.prototype.toString.call(options.body) : 'none',
      error: e instanceof Error ? {
        message: e.message,
        name: e.name,
        stack: e.stack,
      } : String(e),
    };
    console.error('[Turso HTTP] Request failed:', JSON.stringify(errorDetails, null, 2));
    throw new Error(`HTTP request failed: ${e instanceof Error ? e.message : String(e)}. URL: ${fullUrl}, Method: ${request.method}, Body size: ${request.body ? request.body.byteLength : 0} bytes`);
  }


  // Set status code
  item.setStatus(response.status);

  // Read response body and push to item
  const responseData = await response.arrayBuffer();
  if (responseData.byteLength > 0) {
    item.pushBuffer(responseData);
  }

  // Mark as done
  item.done();
}

/**
 * Process a full read request (atomic file read)

View on GitHub (pinned to bad083fafb)

Solutions

  1. Check the logged error name/message first — 'Network request failed' means transport-level failure, cert errors mention TLS
  2. Verify the URL is reachable from the device (not just your laptop) and the scheme survives normalizeUrl (libsql:// is mapped to https://)
  3. Add retry with backoff around operations that can trigger remote IO, treating transient offline windows as expected
  4. For TLS issues, ensure a valid certificate chain or configure appropriate trust in the native network stack

Example fix

// before
const rows = await stmt.all(); // throws: HTTP request failed: Network request failed. URL: https://..., Method: POST, ...

// after
async function withNetworkRetry<T>(fn: () => Promise<T>, tries = 3): Promise<T> {
  for (let i = 0; ; i++) {
    try { return await fn(); }
    catch (e) {
      if (i < tries - 1 && /HTTP request failed/.test(String(e.message))) {
        await new Promise(r => setTimeout(r, 200 * (i + 1)));
        continue;
      }
      throw e;
    }
  }
}
const rows = await withNetworkRetry(() => stmt.all());
Defensive patterns

Strategy: retry

Validate before calling

async function canReach(url: string): Promise<boolean> {
  try {
    const res = await fetch(url, { method: 'HEAD' });
    return res.status < 500 || res.status >= 200; // transport worked
  } catch {
    return false;
  }
}
// gate operations that trigger remote IO
if (!(await canReach(syncUrl))) throw new Error('sync endpoint unreachable');

Type guard

function isHttpRequestFailed(e: unknown): boolean {
  return e instanceof Error && e.message.startsWith('HTTP request failed');
}

Try / catch

async function runWithRetry<T>(fn: () => Promise<T>, tries = 3): Promise<T> {
  for (let i = 0; ; i++) {
    try { return await fn(); }
    catch (e) {
      if (i < tries - 1 && isHttpRequestFailed(e)) {
        await new Promise(r => setTimeout(r, 250 * 2 ** i)); // exponential backoff
        continue;
      }
      throw e;
    }
  }
}
const rows = await runWithRetry(() => stmt.all());

Prevention

When it happens

Trigger: Device offline or DNS resolution failing while a query triggers remote page fetches; TLS handshake rejected (self-signed or expired cert); connection refused/reset mid-request (server restart, network switch); a misbehaving proxy or firewall in React Native's fetch layer.

Common situations: Mobile apps losing connectivity mid-operation; Android emulators with broken DNS; corporate networks MITMing TLS; airplane-mode toggles during a sync; the RN debugger's fetch polyfill behaving differently.

Related errors


AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16). Data as JSON: /api/errors/8fcaa232ff927fba. Report an issue: GitHub.