tursodatabase/turso · error · Error
HTTP request failed: . URL: , Method: , Body size: bytes
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
This is the SDK's wrapper around a failed fetch() for a sync-engine HTTP request: the message embeds the underlying error, the resolved URL, the HTTP method and the body size, and ioProcessor also logs a full '[Turso HTTP] Request failed:' JSON blob to the console. The failing IO item is then poisoned, so the surrounding operation usually dies right after with 'Unexpected status from operation.resume()'. This error is where the real network diagnosis happens.
Solutions
- Read the embedded URL and underlying message - they tell you exactly which endpoint and which network failure (DNS, TLS, refused)
- Android: confirm <uses-permission android:name="android.permission.INTERNET"/> in AndroidManifest.xml, and use 10.0.2.2 (not localhost) when targeting a dev machine from the emulator
- iOS: use https:// endpoints or add an ATS exception for your dev host
- Retry the operation with backoff once connectivity returns; on repeated auth-adjacent failures, verify the authToken is valid for that database
Example fix
// before - emulator cannot reach localhost
const db = await connect({ path: 'r.db', url: 'http://localhost:8080' });
// after
import { Platform } from 'react-native';
const host = Platform.OS === 'android' && __DEV__ ? '10.0.2.2' : 'myserver.example.com';
const db = await connect({ path: 'r.db', url: `https://${host}` }); Defensive patterns
Strategy: retry
Validate before calling
// Connectivity pre-flight before sync operations on mobile
export async function isOnline(): Promise<boolean> {
try {
const res = await fetch('https://your-db-host/ping', { method: 'HEAD' });
return res.ok || res.status < 500;
} catch { return false; }
} Try / catch
catch (e) { if (e instanceof Error && e.message.startsWith('HTTP request failed:')) { await backoff(++attempt); return db.pull(); // retry with backoff while online } throw e; } Prevention
- Add android.permission.INTERNET to AndroidManifest.xml before first run
- Use 10.0.2.2 (not localhost) for dev machines from the Android emulator
- Prefer https:// endpoints so iOS ATS never blocks the request
- Read the embedded URL/method/body-size in the message - it pinpoints the failing request
When it happens
Trigger: connect()/pull()/push()/sync() (or any query on a partial-sync replica that must fetch missing pages) while fetch() throws: DNS failure, TLS error, connection refused, Android missing the INTERNET permission, iOS ATS blocking a plain-http URL, or an emulator hitting localhost instead of 10.0.2.2.
Common situations: Airplane mode / flaky mobile data during sync; local dev server reached via localhost from the Android emulator (use 10.0.2.2); release Android builds without android.permission.INTERNET; http:// (non-TLS) endpoints rejected by iOS App Transport Security; corporate proxies interfering with libsql://-style endpoints normalized to https://.
Related errors
- reader is null
- Unexpected status from operation.resume()
- checkpoint() is only available for sync databases
- GenericFailure
- getAllRows: exceeded
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/8fcaa232ff927fba.
Report an issue: GitHub.
Appendix: 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 244cde92a7)