react-native
react-native copied to clipboard
HTTP Fetch fails with "TypeError: Network request failed" => Resolved
Description
There are 83 issues opened and unanswered about network requests failing with this generic error. The main causes of the pain are:
- Not getting an answer from the team
- The exception is far too generic and does not suggest the origin of the problem
Problem description
Using fetch
to get/post on a HTTPS web server which is using a valid and trusted but not public CA.
- Using Chrome and other apps the requests are always successful and without certificate problems
Sample code in react native:
static async Post(): Promise<string> {
let srv = "my.domain.com";
let port = 5101;
let device = "abcd";
let url = `https://${srv}:${port}/Do/Something?devicename=${device}`;
try {
let response = await fetch(url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-type':'application/json'
},
body: JSON.stringify({
key: 'value',
})
});
if(response.status !== 200) throw new Error(`Can't open ${srv} for ${device} with status ${response.status}`);
return response.json();
}
catch(e) {
console.log(e);
throw(e);
}
}
Solution
Due to Android restrictions, a network_security_config
configuration must be added to the application. It is an xml file that can be added by following these steps:
- Edit the
android/app/src/main/AndroidManifest.xml
- Add the
android:networkSecurityConfig="@xml/network_security_config"
to the<application />
tag - Create the folder
android/app/src/main/res/xml
and inside a file callednetwork_security_config.xml
- If you don't want to install the CA in the Android certificates, add the folder
android/app/src/main/res/raw
Variant 1: using the certificates added manually to Android.
In this case the CA must be visible in the User Certificates in the Android Settings. Try using them by opening a website that uses those certificates in Chrome to verify they are valid and correctly installed.
Content of the network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<!-- Localhost config is NEEDED from react-native for the bundling to work -->
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">127.0.0.1</domain>
<domain includeSubdomains="true">10.0.0.1</domain>
<domain includeSubdomains="true">localhost</domain>
</domain-config>
<domain includeSubdomains="true">my.domain.com</domain>
<trust-anchors>
<certificates src="user"/>
<certificates src="system"/>
</trust-anchors>
</domain-config>
</network-security-config>
The <certificates src="user"/>
is the one giving access to the certificates installed manually.
Variant 2: using a certificate bundled with the app
You should export (using ssl) a pem certificate containing just the public key, naming it "ca" (no extension). Copy the certificate in the raw
folder
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<!-- Localhost config is NEEDED from react-native for the bundling to work -->
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">127.0.0.1</domain>
<domain includeSubdomains="true">10.0.0.1</domain>
<domain includeSubdomains="true">localhost</domain>
</domain-config>
<domain includeSubdomains="true">my.domain.com</domain>
<trust-anchors>
<certificates src="@raw/ca"/>
<certificates src="system"/>
</trust-anchors>
</domain-config>
</network-security-config>
Important note (added on June 22, 2022)
The local traffic (with the packager) must be unencrypted. For this reason the <domain-config />
must contain the clearTrafficPermitted=true
.
It is also important adding the ip addresses used from react-native when debugging otherwise the application will crash because of the android:networkSecurityConfig="@xml/network_security_config"
attribute. If you see the app crashing, take not of the ip used internally from react native and add it/them to this list. For example:
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">127.0.0.1</domain>
<domain includeSubdomains="true">10.0.0.1</domain>
<domain includeSubdomains="true">10.0.1.1</domain>
<domain includeSubdomains="true">10.0.2.2</domain>
<domain includeSubdomains="true">localhost</domain>
</domain-config>
Requested fix: please never throw exceptions with a generic message, they are only a huge pain.
Version
0.67.0
Output of npx react-native info
info Fetching system and libraries information... System: OS: Windows 10 10.0.19044 CPU: (8) x64 Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz Memory: 8.20 GB / 31.93 GB Binaries: Node: 16.13.0 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.4 - C:\Program Files (x86)\Yarn\bin\yarn.CMD npm: 8.1.3 - C:\Program Files\nodejs\npm.CMD Watchman: Not Found SDKs: Android SDK: API Levels: 19, 23, 25, 26, 27, 28, 29, 30 Build Tools: 19.1.0, 21.1.2, 22.0.1, 23.0.1, 23.0.3, 26.0.2, 27.0.0, 28.0.0, 28.0.3, 29.0.2, 30.0.2 System Images: android-27 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom Android NDK: 22.1.7171670 Windows SDK: AllowDevelopmentWithoutDevLicense: Enabled AllowAllTrustedApps: Enabled Versions: 10.0.10586.0, 10.0.14393.0, 10.0.15063.0, 10.0.16299.0, 10.0.17134.0, 10.0.17763.0, 10.0.18362.0, 10.0.19041.0 IDEs: Android Studio: Version 2020.3.0.0 AI-203.7717.56.2031.7935034 Visual Studio: 17.1.32104.313 (Visual Studio Enterprise 2022), 16.11.32002.261 (Visual Studio Enterprise 2019) Languages: Java: 1.8.0_302 npmPackages: @react-native-community/cli: Not Found react: 17.0.2 => 17.0.2 react-native: 0.66.4 => 0.66.4 react-native-windows: Not Found npmGlobalPackages: react-native: Not Found
Steps to reproduce
Use the above code to make an HTTPS request to a website protected with certificates that are not public. They will not succeed with a generic exception (as for the issue title)
Repeat the request to a public website and it will succeed. The issue is the exception being too generic.
Snack, code example, screenshot, or link to a repository
No response
It looks like the underlying okhttp library has quite good error detection and reporting. Somehow though, either the react-native networking layer, or the whatwg-fetch doesn't capture that!
It is an habit in this repo to ignore important issues (not only this one) for a very long time. I start believing RN is not that worthy to invest in.
I have same issue and solve by doing this, you can try
https://github.com/facebook/react-native/issues/24627#issuecomment-1049496059
Thank you @hoaxvo16 but I already posted the solution in this thread. My request is react-native providing a decent error so that nobody else has to spend hours in trying to resolve it. Also, since this an OSS project, it would be nice for some of the owner to "say something" instead of infinite silence.
@raffaeler yeah i know, took me over 3 hours to solve this, good thing is you learned something new :D
My issue was fixed when I restarted the emulator
I am still having the same issue! im trying to connect my react native app to django. i am using JWT. im trying to send a post method to my api but I get "TypeError: Network request failed" => Resolved every time i press the sign in button. i am using a real android device. im new to react so it is been very hard to solve this problem! can anybody help me pls? i already try all methods above but none seem to work
fixed TypeError: Network request failed
when upload file to http not https with Android debug builds
I have this problem connecting with my hosted API (with a valid SSL certificate from Let's Encrypt) on Android Level 21 (Android 5), 22 (Android 5.1), 23 (Android 6) and 24 (Android 7).
After trying both variant 1 and 2 without success, I gave up and removed support for these Android versions (represent like 5% of market share to this day).
No idea what's happening, the error doesn't help π
@nelsonprsousa if the certificate on the API side is publicly verifiable, you should not have this issue at all. My issue was about telling Android+React Native how to trust a private CA.
- double check that your cerificate is correctly deployed by browsing the API from a browser (I assume it is)
- verify the internal android error using
adb logcat
@nelsonprsousa if the certificate on the API side is publicly verifiable, you should not have this issue at all. My issue was about telling Android+React Native how to trust a private CA.
- double check that your cerificate is correctly deployed by browsing the API from a browser (I assume it is)
- verify the internal android error using
adb logcat
Here's my API (checking on Desktop Chrome):
I am assuming it is publicly verifiable.
However, on those Android versions (from API 22 to API 24), I have the "Network request failed" error.
I noticed that trying to directly open the website on Chrome on those old Android versions brings this error, it should be related:

Certificate viewer:

So yeah, something weird on old Android version validating certificates?!
@nelsonprsousa if this behavior happens only on older Android version, it is possible that the CA used by letsencrypt was not already available on those versions. If you scroll in the mobile Chrome app, you should see some hint about the CA not being trusted or another error like that
@nelsonprsousa if this behavior happens only on older Android version, it is possible that the CA used by letsencrypt was not already available on those versions. If you scroll in the mobile Chrome app, you should see some hint about the CA not being trusted or another error like that
yeap.. I was reading on Google and there are some problems with letsencrypt and old Android versions that I don't fully understood.
Do you think that the solution you gave of bundling the certificate will solve this problem (already tried without success), or it is something else and I just hijacked this discussion? π
yeap.. I was reading on Google and there are some problems with letsencrypt and old Android versions that I don't fully understood.
Android ships a number of CAs that can only be updated with official security patches. If your CA was not shipped or updated at that time, of course it can't work.
Do you think that the solution you gave of bundling the certificate will solve this problem (already tried without success), or it is something else and I just hijacked this discussion? π
Bundling the certificate is a good solution whenever you need to use Android in an enterprise environment that works with a private CA. In your case, you could try embedding the server certificate: exporting the CA (the one used by your letsencrypt certificate) from Windows in, converting with openssl, etc.. Not sure if it can work, it's not the scenario I described ad the beginning (and yes, you hijacked the thread π )
yeap.. I was reading on Google and there are some problems with letsencrypt and old Android versions that I don't fully understood.
Android ships a number of CAs that can only be updated with official security patches. If your CA was not shipped or updated at that time, of course it can't work.
Do you think that the solution you gave of bundling the certificate will solve this problem (already tried without success), or it is something else and I just hijacked this discussion? π
Bundling the certificate is a good solution whenever you need to use Android in an enterprise environment that works with a private CA. In your case, you could try embedding the server certificate: exporting the CA (the one used by your letsencrypt certificate) from Windows in, converting with openssl, etc.. Not sure if it can work, it's not the scenario I described ad the beginning (and yes, you hijacked the thread π )
I'll try to find a solution for this specific problem elsewhere. Thank you for your support π
this work for me
I am also facing same issue. my endpoint is https and not http. My other internet requests are working like those with Amplify
@MuhammadAbdullah54321 this issue is strictly related to fetching with HTTPS where the server is using a private or self-signed certificate. In this case, if you carefully follow my points you should resolve the issue.
It is very bad that meta is not even answering or even checking the issues. This should be clarified and be part of the official documentation.
Check if your SSL is properly configured here.
Check if your SSL is properly configured here.
This does not make any sense. The point of this entire thread is to use a non public CA as stated in the initial post, which is extremly common in any enterprise scenario.
The link you posted is a service that can only verify public websites. Also, I strongly reccomend to verify TLS (SSL does not exist anymore) using openssl utilities which are the most updated.
@raffaeler out of curiosity? What is your backend stack?
The backend is ASP.NET Core but this doesn't make any difference. Any fetch on HTTPS involving a private CA would trigger the same issue.
I realized I was using the http version of the endpoint so then I switched it to https and it worked.
The backend is ASP.NET Core but this doesn't make any difference. Any fetc
I'm too using .net core facing the same issue, did you find any solution for it ?
I'm too using .net core facing the same issue, did you find any solution for it ?
Yes, I wrote "Resolved" in the title for a reason :-) In the very first post I wrote the step-by-step to resolve this.
Anyway I am totally scared of Meta not taking in account the community about this. It's a real shame.
Lemme just jump in that I'm always an advocate for bubbling as much error info up the stack as possible. There are those of us who go to great lengths, perhaps even cursed lengths, to make use of the info that is available from web fetch
. It does actually make a big difference in debugging for those of us who go to these lengths, it's saved me untold hours of debugging, and its vastly more useful than the standard "failed to fetch" network error. If I had the time, and lacked the extreme disdain for Java, I'd write the patch myself!
Lemme just jump in that I'm always an advocate for bubbling as much error info up the stack as possible. There are those of us who go to great lengths, perhaps even cursed lengths, to make use of the info that is available from web
fetch
. It does actually make a big difference in debugging for those of us who go to these lengths, it's saved me untold hours of debugging, and its vastly more useful than the standard "failed to fetch" network error. If I had the time, and lacked the extreme disdain for Java, I'd write the patch myself!
Exactly! And let me say that there is a huge difference between creating a library for internal or public use. It looks like that some Meta developers are bullying the devs outside their company by not propagating the error as it should be in any good framework.
BTW this happens too often in many frameworks when you get errors like "file not found" without the name, etc. etc.
Yup, preaching to the choir here! I go to like a million times more effort than any other developer I know to (a) check for error codes (usually just bubbling to the UI for webapps) and (b) get the most specific error information possible to show the user. It's 10x more effort, but it's way less confusion and effort to debug basically every kind of bug I ever see.
For the entertainment of other readers, here's two issues I've opened about goofy issues I encounter when errors are not super well reported (or reportable) https://github.com/puma/puma/issues/2894 https://github.com/nodejs/node/issues/43439
@ariccio BTW with nodejs C++ addons I lost any hope. Sometimes ago I created a generic in-process interop layer to execute any C# code from nodejs (hosting the CLR) and it was like opening the Pandora's Box.