How to Fix NET::ERR_CLEARTEXT_NOT_PERMITTED on Android

Few Android errors feel as confusing as NET::ERR_CLEARTEXT_NOT_PERMITTED. Your app may work perfectly in a browser, run fine on older devices, and then suddenly fail inside an Android WebView or emulator. The good news is that this error is usually not a server crash or a mysterious networking bug; it is Android blocking insecure traffic by design.

TLDR: NET::ERR_CLEARTEXT_NOT_PERMITTED means your Android app is trying to load an HTTP URL instead of HTTPS, and Android is refusing it for security reasons. For example, if a WebView loads http://example.com on Android 9 or newer, it may fail unless cleartext traffic is explicitly allowed. In a typical support case, switching 20 API calls from HTTP to HTTPS can fix nearly all occurrences without changing app logic. If HTTPS is not possible, you can allow HTTP for specific domains using a network security configuration.

What This Error Actually Means

The message NET::ERR_CLEARTEXT_NOT_PERMITTED appears when an Android app attempts to send or receive unencrypted traffic. “Cleartext” simply means data sent in plain text, usually through http:// rather than https://. Since Android 9, also known as API level 28, cleartext traffic is disabled by default for many apps.

This is a security feature. Without HTTPS, data can potentially be intercepted or modified between the user and the server. That might include login tokens, personal details, form submissions, or configuration files. Android blocks this kind of traffic to encourage safer app behavior.

Where You Usually See It

This error is especially common in apps that use WebView, hybrid frameworks, or custom API connections. You might see it in:

  • Android WebView when loading a website using http://
  • React Native or Flutter apps calling an insecure API endpoint
  • Local development using IP addresses such as http://192.168.1.20
  • Older backend services that never received an SSL certificate
  • Redirect chains where an HTTPS page redirects to HTTP

The tricky part is that your original URL may look safe, but a script, image, iframe, or redirect may still call an insecure resource. That is why checking the entire request flow matters.

Fix 1: Use HTTPS Instead of HTTP

The best and most future-proof fix is simple: replace HTTP URLs with HTTPS URLs. If your app currently loads:

http://example.com

Change it to:

https://example.com

This applies to WebView URLs, REST API endpoints, image paths, JavaScript files, CSS files, and any external resources. If you control the website or API, install an SSL certificate. Services such as Let’s Encrypt make this free and widely supported.

After switching to HTTPS, test the app again and watch for mixed content. A page loaded over HTTPS can still fail or behave strangely if it tries to fetch images, scripts, or data from HTTP sources.

Fix 2: Allow Cleartext Traffic for the Whole App

If you cannot immediately move to HTTPS, you can allow cleartext traffic in your Android app. This is easy, but it is not the safest option. Use it only when necessary, especially for testing or internal applications.

Open your AndroidManifest.xml file and add android:usesCleartextTraffic="true" inside the <application> tag:

<application
    android:usesCleartextTraffic="true"
    android:theme="@style/AppTheme"
    android:label="@string/app_name">
</application>

This tells Android that the app is allowed to use HTTP traffic. It is the fastest fix, but it also creates the broadest permission. If your app handles sensitive data, a more targeted configuration is better.

Fix 3: Allow HTTP Only for Specific Domains

A cleaner approach is to permit cleartext only for selected domains. This gives you more control and avoids opening the entire app to insecure traffic.

First, create a file in:

res/xml/network_security_config.xml

Then add a configuration like this:

<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">example.com</domain>
    </domain-config>
</network-security-config>

Next, reference it in AndroidManifest.xml:

<application
    android:networkSecurityConfig="@xml/network_security_config"
    android:theme="@style/AppTheme"
    android:label="@string/app_name">
</application>

This method is ideal when only one development server, staging domain, or legacy API still requires HTTP. It also makes your security intention clearer to future developers.

Fix 4: Handle Localhost and Development Servers

Development environments often trigger this error. For example, your Android emulator may need to call a local server. Instead of using localhost, Android emulators commonly access the host machine through:

http://10.0.2.2:3000

If you are testing on a physical device, you may use your computer’s local network IP, such as:

http://192.168.1.50:3000

Because these are HTTP addresses, Android may block them. You can temporarily allow cleartext traffic during development, but avoid shipping that setting broadly in production. A practical pattern is to use separate build configurations: allow HTTP in debug builds, require HTTPS in release builds.

Fix 5: Check Redirects and Hidden HTTP Resources

Sometimes the URL in your code is not the real problem. You might load an HTTPS page, but the server redirects to an HTTP address. Or the page may include an insecure script, image, font, or API request.

To investigate, try these steps:

  1. Open the URL in a desktop browser and inspect the Network tab.
  2. Look for requests beginning with http://.
  3. Check whether your HTTPS URL redirects to HTTP.
  4. Update backend settings, CDN rules, or asset links if needed.
  5. Clear app cache and test again on Android 9 or newer.

This is especially important for WebView apps. A single insecure resource can cause confusing behavior, even when the main page URL looks correct.

Fix 6: Confirm WebView Settings

If your issue appears in an Android WebView, review your WebView implementation. The cleartext policy is controlled by Android networking rules, but WebView settings can still affect loading behavior.

Make sure your WebView is loading the correct URL and that JavaScript, storage, and mixed content settings are configured intentionally. For mixed content, Android provides options such as allowing or blocking insecure content on secure pages. However, allowing mixed content should be treated as a temporary workaround, not a final security strategy.

In general, do not use WebView settings to hide a server-side security problem. If the resource can be served over HTTPS, fix it at the source.

Common Mistakes to Avoid

  • Allowing all cleartext traffic in production: This may solve the error but weakens app security.
  • Forgetting subdomains: If your API uses api.example.com, include the correct domain or enable subdomains.
  • Testing only on old Android versions: The error may not appear until Android 9 or later.
  • Ignoring redirects: An HTTPS request can still become HTTP after a server redirect.
  • Assuming it is a DNS issue: This error is usually about protocol security, not domain resolution.

Which Fix Should You Choose?

If you own the server, choose HTTPS. It is safer, cleaner, and expected by modern Android versions. If you are working with a temporary development server, allow cleartext only for debug builds or specific local addresses. If you depend on a third-party HTTP-only service, use a domain-specific network security configuration while planning a migration away from that dependency.

The key is to avoid treating NET::ERR_CLEARTEXT_NOT_PERMITTED as just another annoying error message. It is Android telling you that the app is trying to communicate in a less secure way. Fixing it properly improves reliability, protects users, and prepares your app for modern platform requirements.

In most cases, the solution is not complicated: find the HTTP request, replace it with HTTPS, and test the complete request chain. When HTTPS is not immediately available, use Android’s network security configuration carefully and as narrowly as possible.

I'm Ava Taylor, a freelance web designer and blogger. Discussing web design trends, CSS tricks, and front-end development is my passion.
Back To Top