Header Ads

server that is down, HTTPS and certificate problems, a wrong URL

Seeing “Http failure response for … : 0 Unknown Error” in your Angular or Ionic app? Status 0 hides the real reason, so this guide shows how to find it in DevTools and fix the 7 most common causes: CORS, a server that is down, HTTPS and certificate problems, a wrong URL, phone and emulator networking, and blockers.

Your Angular or Ionic app calls your API, and the console shows this instead of a useful message:

ERROR HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: 'Unknown Error',
url: 'http://localhost:3000/api/users', ok: false, …}

Http failure response for http://localhost:3000/api/users: 0 Unknown Error

The most confusing part is that there is no server message, no JSON and no real error code. That is normal for this error, and the next section explains why.

What Does Status 0 Mean?

HTTP status codes such as 200, 404 or 500 come from a server. Status 0 is not a real HTTP status. It is what the browser reports when the request never produced a response your code is allowed to read. The request may have been blocked by the browser, or it may never have reached the server at all.

Angular cannot tell you more, because the browser hides the details for security reasons. The real reason is shown only in the browser’s own DevTools. That is where you should look first.


Step 1: Find the Real Reason in DevTools

Open DevTools in your browser and check two tabs:

  • Console: look for red messages that mention CORS, Mixed Content or a certificate.
  • Network: click the failed request. The status column shows (failed), and the message next to it, such as net::ERR_CONNECTION_REFUSED, names the cause.
What you seeLikely causeGo to
blocked by CORS policyThe server does not allow your origin or headerStep 3
net::ERR_CONNECTION_REFUSEDServer is not running, or the wrong port or addressSteps 2 and 6
Mixed Content messageAn HTTPS page calls an HTTP APIStep 4
net::ERR_CERT_AUTHORITY_INVALID or other ERR_CERT_...Self-signed, expired or mismatched certificateStep 5
net::ERR_NAME_NOT_RESOLVEDWrong host name, or DNS problemStep 6
net::ERR_CLEARTEXT_NOT_PERMITTEDPlain HTTP blocked in the Android appStep 7
net::ERR_BLOCKED_BY_CLIENTAn ad blocker or browser extension blocked itStep 8


Step 2: Check That the Server Is Reachable

Test the API without the browser. If this also fails, the problem is the server or the network, not Angular:

curl -i http://localhost:3000/api/users

If curl cannot connect, check these:

  • The server process is running and did not crash. Look at its terminal output.
  • The port in your Angular code matches the port the server listens on.
  • The server did not start on a different port because the usual one was busy.
  • A firewall is not blocking the port, especially when you call the API from another device.


Step 3: Fix CORS

When the console says blocked by CORS policy, the server did not send the permission headers the browser needs, and Angular reports it as status 0. The fix is on the server: allow your app’s exact origin and any custom headers such as Authorization. One detail that surprises many people is that error responses need the CORS headers too. If your API crashes with a 500 before the CORS middleware runs, the browser shows a CORS error and status 0 instead of the real 500. I explain the full setup, including Ionic and Capacitor origins, in my guide on fixing CORS errors in Node.js, Angular and Ionic.


Step 4: Fix Mixed Content (HTTPS Page, HTTP API)

If your app is served over HTTPS but calls an http:// API, the browser blocks the request. The console message starts with Mixed Content. This often appears after you deploy: everything worked on http://localhost, but the live site uses HTTPS. The fix is to serve your API over HTTPS as well, and to keep the base URL in one place:

// environment.prod.ts
export const environment = {
production: true,
apiUrl: 'https://api.example.com'
};

// in a service
this.http.get(`${environment.apiUrl}/api/users`);

My guide on securing your Node.js API with HTTPS and SSL covers the server side.


Step 5: Fix Certificate Problems

An HTTPS request fails with status 0 when the browser does not trust the server’s certificate. Typical causes are a self-signed certificate, an expired certificate, or a certificate issued for a different domain name than the one in your URL. The Network tab shows a message starting with net::ERR_CERT_.

  • Production: use a certificate from a trusted authority, such as a free Let’s Encrypt certificate, and make sure it covers the exact host name you call and has not expired.
  • Local development with HTTPS: create a certificate that your computer trusts, using a tool such as mkcert, instead of clicking through browser warnings.

Mobile apps are stricter than desktop browsers about certificates, so a self-signed certificate that you accepted once in Chrome will still fail inside your app.


Step 6: Check the API URL and Host Name

A small typo or a stale URL causes many status 0 errors. Check the exact URL in the failed request, and compare it letter by letter:

  • Wrong host name, which shows ERR_NAME_NOT_RESOLVED.
  • Wrong port number, or http where you meant https.
  • A missing /api prefix, or one added twice.
  • The development URL left in the production build, so the deployed app calls localhost. Use the environment files, as in Step 4, and check which one your build uses.


Step 7: Fix Phones and Emulators (Ionic and Capacitor)

This is the most common cause in Ionic apps that work in the browser but fail on a device:

  • localhost means the device itself. On the Android emulator, your computer is reachable at 10.0.2.2. On a real phone, use your computer’s local network IP address, and keep both on the same Wi-Fi.
  • The server must accept outside connections. A server that listens only on 127.0.0.1 cannot be reached from a phone. Start it on all interfaces, for example app.listen(3000, '0.0.0.0'), and allow the port through your firewall.
  • Plain HTTP is blocked on Android. The error is ERR_CLEARTEXT_NOT_PERMITTED. Use HTTPS, or for local development only, set server: { cleartext: true } in capacitor.config.ts and run npx cap sync android.
  • iOS also restricts plain HTTP through App Transport Security. Use HTTPS, or add a development-only exception in your iOS project settings, and remove it before release.


Step 8: Rule Out Ad Blockers, Extensions and VPNs

If the Network tab shows net::ERR_BLOCKED_BY_CLIENT, something in your browser blocked the request. Ad blockers sometimes block URLs that contain words such as ads, track or analytics, even in your own API. Open the app in a private window with extensions disabled, or rename the endpoint. A company VPN, proxy or antivirus program can also interfere, so test on another network if everything else looks right.


Step 9: Show a Clear Message Instead of “Unknown Error”

Once the cause is fixed, make your app handle status 0 on purpose, so users do not see a blank screen when the network drops:

import { HttpErrorResponse } from '@angular/common/http';
import { catchError, throwError } from 'rxjs';

this.http.get('/api/users').pipe(
catchError((err: HttpErrorResponse) => {
if (err.status === 0) {
console.error('Network or CORS error', err);
this.message = 'Cannot reach the server. Check your connection and try again.';
} else {
this.message = `Server error ${err.status}`;
}
return throwError(() => err);
})
).subscribe((users) => (this.users = users));

You can put the same logic into an HTTP interceptor so every request gets consistent error handling.


Debug Checklist

  1. Open DevTools and read the Console and the Network status for the failed request.
  2. Run the same URL with curl. If it fails, fix the server or network first.
  3. Check the exact URL, port and protocol in the failed request.
  4. If the console mentions CORS, check the server headers, including on error responses.
  5. On a phone or emulator, replace localhost with 10.0.2.2 or your computer’s IP, and check the cleartext settings.
  6. Test in a private window with extensions off.


Conclusion

Status 0 is not an error from your server. It means the browser stopped the request, or the request never arrived. Open DevTools and read the real reason, then fix that layer: the server, CORS, HTTPS, the certificate, the URL, the device network or a blocker. Add a clear error message in your app, and the next outage will be easy to understand.

Related Guides

Post a Comment

0 Comments