# Flutter: “HttpException: Connection closed before full header was received”

> HttpException: Connection closed before full header was received. The server or a proxy dropped the connection. Check the server log, timeouts and retries.

Canonical: https://app369.com/fix/flutter-httpexception-connection-closed-before-full-header/
Last updated: 2026-11-08

An HTTP request from a Flutter or Dart app fails with HttpException: Connection closed before full header was received (with package:http it arrives as a ClientException). The connection opened, then closed before the server sent a response. Either the server or a proxy dropped it, or the client reused a keep-alive connection the server had already closed.

**Short answer**

Check the server log for the request first: a crash, a timeout or a request size limit closes the connection without a response. If it fails only now and then, the server is closing idle keep-alive connections: retry the request once with RetryClient, and make sure the URL scheme matches the port (http vs https). For local servers on the emulator, use 10.0.2.2.

## **Why the connection closes early, and the fix**

1. 01 ### **The server crashed or timed out on this request** A server that throws, runs out of memory, or hits a proxy or load balancer timeout can close the socket without answering. The server or proxy log for that time shows the real error; fix it there. Large uploads can also hit a body size limit (for example nginx client_max_body_size).
2. 02 ### **A reused keep-alive connection the server already closed**
  > “Gets and sets the idle timeout of non-active persistent (keep-alive) connections. The default value is 15 seconds.” [**Dart, HttpClient.idleTimeout**](https://api.dart.dev/dart-io/HttpClient/idleTimeout.html) Dart keeps connections open for reuse. If the server closes idle connections sooner than the client stops reusing them, the next request on that connection fails at random. Retry safe requests once, and lower the client idle timeout below the server’s by passing your own HttpClient through IOClient (mobile and desktop; dart:io isn’t available on the web).```
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart';
import 'package:http/retry.dart';

final inner = HttpClient()..idleTimeout = const Duration(seconds: 5);
final client = RetryClient(
  IOClient(inner),
  retries: 2,
  whenError: (error, _) => error is http.ClientException,
);
```
3. 03 ### **Retrying without a plan**
  > “package:http/retry.dart provides a class RetryClient to wrap an underlying http.Client which transparently retries failing requests.” [**pub.dev, package:http**](https://pub.dev/packages/http) RetryClient only retries on a 503 response by default, so connection errors need whenError. Retry only requests that are safe to repeat, such as GET, or POSTs your server deduplicates.
4. 04 ### **http sent to an https port, or the wrong host** Plain http to a port that expects TLS (or the reverse) makes the server drop the connection. Check the scheme and port, and on the Android emulator call your computer at 10.0.2.2, not localhost.

Checked against the vendor’s docs on November 8, 2026: [Dart API: HttpClient.idleTimeout](https://api.dart.dev/dart-io/HttpClient/idleTimeout.html); [pub.dev: package:http (Client, RetryClient)](https://pub.dev/packages/http).

## **Rather hand it over?**

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

- [from $450**App Fix Ticket**One reproducible bug in an existing mobile or web app, diagnosed and fixed.**See scope and start**](https://app369.com/fixed-price/flutter-firebase-bug-fix/)
- [from $450**AI-Built App Rescue**A Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.****No issues worth fixing, no charge.**** If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.**See scope and start**](https://app369.com/fixed-price/ai-app-rescue/)

Related: [**Flutter “SocketException: Connection refused”**](https://app369.com/fix/flutter-socketexception-connection-refused/) · [**Flutter “SocketException: Failed host lookup”**](https://app369.com/fix/flutter-socketexception-failed-host-lookup/) · [**Flutter “HandshakeException: CERTIFICATE_VERIFY_FAILED”**](https://app369.com/fix/flutter-handshakeexception-certificate-verify-failed/) · [**Flutter “type 'Null' is not a subtype of type 'String'”**](https://app369.com/fix/flutter-type-null-is-not-a-subtype-of-type-string/)

Questions

## **More on this error**

<details>

<summary>**Should I create a new http.Client for every request? **+</summary>

No. package:http recommends one Client for many requests to the same server, closed when you are done. A new client per request hides the keep-alive issue but costs a fresh connection each time.

</details>

<details>

<summary>**It only happens on the emulator with my local server. Why? **+</summary>

Local dev servers often close connections fast or restart on file changes. Check the server console when it fails, and retry once in development.

</details>

<details>

<summary>**Can you fix it for me? **+</summary>

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.

</details>

A different error?

## **Describe it and get a written quote**

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.

[**Describe your problem **→](https://app369.com/contact/) [**All fixes**](https://app369.com/fix/)