Capturing Flutter Traffic
By default, Flutter applications that use Dart's dart:io networking stack don't automatically follow the proxy configured on the mobile device (Wi-Fi proxy / system proxy). As a consequence, even when the device is configured to use the Fiddler Everywhere proxy, you might not see any traffic from the Flutter app in Fiddler Everywhere.
This article shows how to make a Flutter app use the device proxy settings so that Fiddler Everywhere can capture the app's HTTP and HTTPS traffic.
Prerequisites (Device setup)
Before changing your Flutter code, ensure the device is already configured to send traffic through Fiddler Everywhere:
- Configure the mobile device to use Fiddler Everywhere as a proxy:
- Android: Capturing Android Traffic
- iOS: Capturing iOS Traffic
- Install and trust the Fiddler CA certificate on the device (required to decrypt HTTPS):
- Follow the platform steps in the Android/iOS articles above.
Solution
Use the http_proxy Flutter plugin to read the mobile device proxy configuration and apply it to Dart's HTTP client via HttpOverrides. This makes common Flutter HTTP stacks (for example, package:http via IOClient, and clients built on dart:io) route traffic through the proxy configured on the device.
-
Add the dependency to your
pubspec.yaml(use the latest version from pub.dev):yamldependencies: http_proxy: ^1.2.3 -
Initialize
HttpOverrides.globalbeforerunApp()and before any network calls:dartimport 'dart:io'; import 'package:flutter/widgets.dart'; import 'package:http_proxy/http_proxy.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); HttpProxy httpProxy = await HttpProxy.createHttpProxy(); HttpOverrides.global = httpProxy; runApp(MyApp()); } -
Rebuild and restart the application.
If the device proxy is configured to point to the Fiddler Everywhere host, you should now see the Flutter app sessions appear in Fiddler Everywhere.
Notes for common Flutter HTTP stacks
dart:io(HttpClient) respectsHttpOverrides.global, so it will use the device proxy when configured as shown above.package:httpon mobile typically usesdart:iounder the hood (for example viaIOClient), so it will usually followHttpOverrides.globalas well.dioon Android/iOS typically uses adart:ioadapter by default, so it will usually followHttpOverrides.global. If you use a custom adapter or a native networking plugin/SDK, proxy handling may differ.WebViewtraffic and some native SDK/plugin traffic may not go throughdart:ioat all, so settingHttpOverrides.globalmight not affect it.
Troubleshooting
I only see CONNECT tunnels (port 443)
This usually means the app is proxying traffic, but TLS decryption fails (the app does not trust the user-installed CA).
- Android apps often need an explicit debug-time configuration to trust user-added CAs.
- Follow the steps in Capture Mobile Application Traffic.
If you can’t (or don’t want to) change the Android app network security config, you have a few other development-time options:
-
Dart-only traffic (debug-only): accept the interception certificate in code. For requests that go through
dart:io, you can override certificate validation in yourHttpOverrides. This is useful to confirm that the issue is CA trust, but it should never be enabled in production builds.dartimport 'dart:io'; class DebugHttpOverrides extends HttpOverrides { HttpClient createHttpClient(SecurityContext? context) { final client = super.createHttpClient(context); client.badCertificateCallback = (cert, host, port) => true; return client; } } // In main() before runApp(): // HttpOverrides.global = DebugHttpOverrides(); -
Use an emulator or a rooted device and install the Fiddler CA as a system CA. On Android 7+ (API 24+), many apps ignore user-installed CAs by default, but still trust system CAs. Installing the Fiddler CA into the system store can enable TLS decryption without changing app code (requires elevated privileges and is typically done only on test devices/emulators).
-
Check for certificate pinning. If the app (or one of its SDKs) pins certificates, it will reject the MITM certificate even if the CA is trusted. In that case, you need a debug build with pinning disabled/relaxed, or an SDK-specific way to allow a custom trust store.
I still see no traffic from the Flutter app
- Confirm the device proxy is set (Wi-Fi proxy) and that browser traffic from the same device is visible in Fiddler Everywhere.
- Ensure
HttpOverrides.globalis set before any networking is initialized (keep it at the very start ofmain()as shown above). - If the app uses native networking outside of
dart:io(some plugins, SDKs, orWebViewtraffic), it may follow different proxy and certificate rules.
Proxy and certificate changes are intended for development and debugging. Avoid shipping a production build with custom trust or proxy behavior enabled.