Flutter (Android): java.io.IOException: Cleartext HTTP traffic to api.example.com not permitted
Android 9+ blocks plain http:// requests by default; the app must use HTTPS or explicitly allow cleartext for that host.
Cleartext HTTP traffic to not permittedjava.io.IOException: Cleartext HTTP traffic not permittedCLEARTEXT communication to not permitted by network security policy Meaning
Network security config prohibits cleartext since API 28. Prefer switching the API to HTTPS. For development servers, add a network_security_config.xml allowing cleartext for specific domains, or android:usesCleartextTraffic="true" for debug only.
Common causes
- Calling an http:// URL on Android 9+
- Local dev server over HTTP
- Redirect from HTTPS to HTTP
- WebView loading http content
- Release build using debug-only manifest
⚡ Quick fix
- Use HTTPS endpoints
- For dev add
android:usesCleartextTraffic="true"in a debug manifest or a domain-specific config - Never allow cleartext globally in release
Detailed fix by platform
Android
android/app/src/debug/AndroidManifest.xml:<application android:usesCleartextTraffic="true" tools:replace="android:usesCleartextTraffic"/>
How to diagnose
- URL — http or https?
- Build — Debug only?
- Host — Specific domain config?
🔧 Still not fixed?
Many errors look alike. If the steps above didn’t solve it, one of these is probably what you’re facing:
Similar errors
- A Timer is still pending even after the widget tree was disposed Flutter test: A Timer is still pending even after the widget tree was disposed
- Android license status unknown / licenses not accepted flutter doctor: Android license status unknown. Run `flutter doctor --android-licenses` to accept the SDK licenses
- App Transport Security has blocked a cleartext HTTP load iOS: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection (NSURLErrorDomain -1022)
Most viewed in Flutter / Dart
- setState() called after dispose() Flutter: setState() called after dispose(): _MyState#1a2b3 (lifecycle state: defunct, not mounted)
- A RenderFlex overflowed Flutter: A RenderFlex overflowed by x pixels on the right/bottom
- Null check operator used on a null value Dart/Flutter: Null check operator used on a null value
Other ways to find it
Where this error sits
Origin: On your device. Errors that are often confused with or caused by this one (click to open):
🧠 Still stuck? Analyze your error
Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.
💬 What worked for others
No tips yet — did something else fix this for you?
Share what worked for you
Tips are checked by an editor before they appear. Links are removed.
Report a correction or suggest an improvement
Last updated 4 Nov 2026