WebView
ERR_CLEARTEXT_NOT_PERMITTED
HTTPS
Android
Troubleshooting

WebView showing ERR_CLEARTEXT_NOT_PERMITTED although site is HTTPS

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

ERR_CLEARTEXT_NOT_PERMITTED in Android WebView means some request is still trying to use plain HTTP. The confusing part is that the page you typed may begin with https://, but a redirect, script, image, iframe, or API call inside that page can still trigger blocked cleartext traffic.

Why an HTTPS Site Can Still Cause the Error

The top-level URL is only part of the story. A WebView page may:

  • redirect from HTTPS to HTTP
  • load HTTP images, scripts, or stylesheets
  • call an HTTP API with JavaScript
  • embed an HTTP iframe or video resource

From Android 9 onward, cleartext traffic is blocked by default for apps unless you explicitly allow it. So even a mostly HTTPS website can fail if any dependency still uses HTTP.

Inspect What the WebView Is Actually Requesting

Start by enabling WebView debugging and checking the page in Chrome DevTools. That lets you see network requests and redirects instead of guessing.

kotlin
1import android.os.Bundle
2import android.webkit.WebView
3import android.webkit.WebViewClient
4import androidx.appcompat.app.AppCompatActivity
5
6class MainActivity : AppCompatActivity() {
7    override fun onCreate(savedInstanceState: Bundle?) {
8        super.onCreate(savedInstanceState)
9
10        val webView = WebView(this)
11        setContentView(webView)
12
13        WebView.setWebContentsDebuggingEnabled(true)
14        webView.webViewClient = WebViewClient()
15        webView.settings.javaScriptEnabled = true
16        webView.loadUrl("https://example.com")
17    }
18}

Then open chrome://inspect in desktop Chrome and inspect the WebView. If the error comes from a redirect or subresource, the network panel usually makes it obvious.

You can also log requests inside the app:

kotlin
1webView.webViewClient = object : WebViewClient() {
2    override fun shouldInterceptRequest(
3        view: WebView?,
4        request: android.webkit.WebResourceRequest?
5    ): android.webkit.WebResourceResponse? {
6        android.util.Log.d("WebView", "Loading ${request?.url}")
7        return super.shouldInterceptRequest(view, request)
8    }
9}

Fix the Real Cause First

The best fix is to remove the HTTP request from the site or service itself. For example:

  • change hard-coded http:// asset URLs to https://
  • fix misconfigured redirects
  • update API endpoints to HTTPS
  • use protocol-correct embedded resources

If the page is yours, fix it there before changing app policy. Allowing cleartext traffic just to make a broken site load is usually the wrong direction.

It is also worth testing the same URL outside the app. If a desktop browser reports mixed content warnings or you can see an HTTP redirect in its network tools, the problem is confirmed to be on the web side rather than in Android configuration.

Use Network Security Config Only When HTTP Is Truly Required

If you must allow HTTP for a known domain, define it explicitly with a network security config instead of enabling cleartext everywhere.

res/xml/network_security_config.xml

xml
1<?xml version="1.0" encoding="utf-8"?>
2<network-security-config>
3    <domain-config cleartextTrafficPermitted="true">
4        <domain includeSubdomains="true">legacy.example.com</domain>
5    </domain-config>
6</network-security-config>

AndroidManifest.xml

xml
1<application
2    android:networkSecurityConfig="@xml/network_security_config"
3    ... >
4</application>

This should be a last resort for specific legacy systems, not a blanket solution for all web content.

Common Pitfalls

  • Looking only at the initial https:// URL and ignoring redirects and embedded resources.
  • Fixing the app manifest when the real problem is a mixed-content website.
  • Setting usesCleartextTraffic="true" for the whole app when only one legacy domain is involved.
  • Forgetting that JavaScript code inside the page can trigger blocked HTTP API calls too.
  • Watching only the initial navigation and missing later HTTP requests triggered by scripts, ads, or embedded widgets.

Summary

  • 'ERR_CLEARTEXT_NOT_PERMITTED means some request is still using HTTP.'
  • An HTTPS page can still fail because of redirects, subresources, or API calls.
  • Use WebView debugging or request logging to see the actual blocked URL.
  • Prefer fixing the site or endpoint rather than relaxing app security.
  • If HTTP is unavoidable, allow it narrowly with a network security config.

Course illustration
Course illustration

All Rights Reserved.