Yesterday, one of the Android users emailed me and described his issue. When I launch the application on the emulator, it crashes, and as soon as I checked the logs, it stated that “Cleartext HTTP traffic is * not allowed,” and because of this, I am not able to test the functionality of my app.
Is that a real issue in the sense I described, or am I doing something wrong? So, please help me to resolve this issue and I will be grateful to you.
On mail, I reverted the solution to him, and his problem was resolved. After that, I thought I should write a solution to this problem because more people may face this problem while accessing HTTP connections.
Table of Contents
Method to Fix Cleartext HTTP Traffic Not Permitted
This issue can be resolved with multiple methods, so first we will start with the least performant steps, then will gradually increase the complexity.
- Instead of using HTTP, use HTTPS
- Add use usesCleartextTraffic=”true” in AndroidManifest.xml
- Create res/xml/network_security_config.xml and modify AndroidManifest.xml
Instead of using HTTP use HTTPS
The simplest way to fix this is to use an HTTPS connection over HTTP. As you know, an HTTP connection is not a secure way to handshake with a connection. It carries a lot of risks, so to avoid this, Android does not recommend using an HTTP connection after the release of Android Marshmallow.
To avoid this, simply go to the file where you have explicitly declared your IP address and, if possible, change it to HTTPS over HTTP and run the application.
I’m testing the appwrite backend tool on my localhost and using my mobile phone to test functionality, so to reach localhost I need to forward the connection using ngrok.
I know this is not an appropriate example but for the sake of understanding, I have shown you where and how to modify the file.
After making significant changes, run your application by pressing Shift + F10, and you will find your application will work without any errors.
Add use usesCleartextTraffic=”true” in AndroidManifest.xml
What to do when you don’t have an HTTPS connection? Alright, we do have a solution for this. You just need to add a single attribute to the AndroidManifest.xml file that will allow you to use HTTP connections in your Android application.
Open the AndroidManifest.xml file and under the <application> tag, add the specific line that android:usesCleartextTraffic=”true” enables the HTTP connection, which is disabled by default after the release of Marshmallow.
AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest ...> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" ... ... ******** SNIPPED OUT ************ android:usesCleartextTraffic="true" > <activity android:name=".MainActivity" android:exported="true"> ******** SNIPPED OUT ************
Now run your application.
Create res/xml/network_security_config.xml and modify AndroidManifest.xml
If you want to gain more control over the network, then this method will work for you, because here you can add a list of URLs to use cleartextTraffic and make use of custom CAs (Certificate Authorities), certificate pinning, and many other important aspects.
You can refer to Network Security Configuration to learn more.
First and foremost, you need to create a network_security_config file in the XML directory under the RES directory, and I believe you know how to do that, so that’s the reason I’m skipping the basic steps.
Inside the network_security_config.xml, copy-paste the below code snippet and replace the domain name with the actual name.
network_security_config.xml <?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">example.domain.name</domain> </domain-config> </network-security-config>
Add the highlighted line into AndroidManifest.xml to specify the network configuration file under the <application> tag.
AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest ... > <application android:networkSecurityConfig="@xml/network_security_config" ... > ... </application> </manifest>
This method will fail if you are working in a localhost environment or using an HTTP connection just like me.
As of result, this application will crash with the error message “CLEARTEXT communication to ac50-122-177-251-224.ngrok.io not permitted by network security policy”.
To resolve this issue add the <base-config> tag in network_security_config.xml with cleartextTrafficPermitted=”true”.
network_security_config.xml <?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true" /> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">ac50-122-177-251-224.ngrok.io/v1</domain> </domain-config> </network-security-config>
After making the following changes, you can run your applications to test out the working features.
Why did this Error Occur, and What is Cleartext?
The reason for this error is the implementation of the network policy, which does not allow you to use HTTP connections to create a secure connection to transmit data over the network. Till Android Nougat, you can use an HTTP connection without making any changes, but after that, you cannot until you make the necessary changes.
And your last question about cleartext: in simple terms, text or data that is not encrypted is known as “cleartext,” which can be easily read by anyone while passing through the network.
That’s all to resolve Cleartext HTTP traffic not permitted in Android.
As we have discussed multiple methods to resolve the above error, it’s up to you which method you prefer to fix as long as Google recommends you use an HTTPS connection.
You can follow codelab to learn more about the Android Network Security Configuration Codelab.
A man with a tech effusive who has explored some of the amazing technology stuff and is exploring more. While moving towards, I had a chance to work on Android development, Linux, AWS, and DevOps with several open-source tools.