Allow HTTP for a Flutter Development API Without Weakening Release Security
A local API over HTTP may be blocked by Android cleartext policy. Scope any exception to debug builds and keep the production network policy strict.
Confirm the failure is policy, not reachability
An HTTP request can fail because the server is unreachable, the emulator uses the wrong host address, an ADB reverse mapping is missing, or Android blocks cleartext traffic. Read the exception and test the endpoint independently before changing the manifest. CLEARTEXT communication ... not permitted points to policy; connection refused points elsewhere.
Android app policy can be configured through the manifest and a network security configuration. If development requires HTTP, scope the setting to a debug manifest or a debug-only configuration. Keep the release manifest on HTTPS and test the release variant to prove the exception did not leak.
Do not ship a broad allow-all rule
Allowing cleartext to every host can expose credentials and user data on hostile networks. A debug-only wildcard can still make local testing convenient, but it must not be merged into the production source set. Prefer a development endpoint reachable through adb reverse and avoid hardcoding a personal laptop address into an artifact.
Verify the merged manifest for both debug and release variants. Build each one, inspect the resulting network policy, and run a request against the intended host. This catches flavor-specific manifest merges that source inspection alone can miss.
If HTTPS is available in development, use it where practical and configure a development certificate deliberately. Do not disable certificate validation in application code. The right fix identifies whether transport or policy blocked the request and limits any exception to the environment that truly needs it.
Verify whether the request is actually cleartext
Start with the exact exception and request URL. An Android cleartext-policy error differs from connection refusal, DNS failure, invalid certificate, or timeout. Confirm the scheme is http and identify host and port without exposing credentials. If the request is HTTPS, changing cleartext settings is unlikely to fix a certificate or hostname problem. If it is HTTP, find which environment configuration produced that URL before changing the manifest.
Prefer an HTTPS development endpoint when the team has a safe local certificate workflow. When local HTTP is necessary, scope the exception to debug builds and the narrowest host that supports the test. Build variants can merge manifests differently, so inspect the merged manifest for debug and release and make the policy part of a CI assertion.
Keep environment behavior explicit
Physical devices and emulators reach the host differently. A loopback address on the phone refers to the phone; an emulator-specific host bridge or an ADB reverse mapping may be needed for a laptop service. Neither changes Android's cleartext policy. Treat routing and transport security as separate layers: prove the endpoint is reachable, then prove the application policy permits the intended scheme.
If a debug-only exception is used, document its purpose and make release fail closed. Test a release build with an HTTP endpoint and confirm it is blocked, while the intended HTTPS endpoint succeeds. Review network security configuration for debug overrides, trust anchors, and domain scoping. Broad trust of user-installed certificates or all cleartext traffic may be useful on a controlled test device but is not a general production fix.
Do not transmit real user credentials over local HTTP merely because the endpoint is on a development network. Local networks can be observed, and debug builds are often shared more widely than expected. Use disposable test accounts and keep tokens out of logs. A clear environment boundary preserves a convenient development workflow without teaching the release app to accept insecure transport.
Make the test repeatable by recording the build variant, resolved endpoint, device type, and observed exception class. Confirm a secure request from the production variant against a test service with a valid certificate. This guards against the opposite regression too: an overly broad development exception that makes local testing pass while production traffic is accidentally downgraded or sent to a stale host.
Inspect the merged manifest and network security configuration, not only source files. A plugin or flavor can add an unexpected declaration. Test an HTTP endpoint with the release build and confirm it is rejected, then test the intended HTTPS endpoint. This provides evidence that the local exception remains scoped to development and cannot silently become a shipping dependency.
Also test emulator and physical-device routing separately. ADB reverse, an emulator host bridge, and a laptop IP address are different paths. Record which path the debug flavor uses and make the release flavor reject localhost endpoints. This prevents a networking workaround from surviving into a distributable build while still giving developers a clear, repeatable local command.