React Native Network Request Failed Only on Physical Android Device
A network request that works fine on an Android emulator but fails specifically on a physical device almost always comes down to how each environment reaches your local development server differently — an emulator has special networking conveniences a real physical device on the same Wi-Fi network doesn't automatically get.
The Problem
API calls to a local development server work correctly when testing on an Android emulator, but the exact same code fails when running on a real physical Android device:
TypeError: Network request failed
The generic error message doesn't distinguish the specific cause, but the fact that it's environment-specific (emulator works, physical device doesn't) narrows things down significantly.
Why It Happens
Physical devices and emulators reach a local development machine differently, and code written assuming emulator-style networking conveniences breaks on a real device:
- Using
localhostor10.0.2.2(the standard Android emulator alias for the host machine) in your API base URL — these work correctly on an emulator, but have no meaning at all on a physical device, which needs your actual development machine's local network IP address instead - The physical device and development machine aren't actually on the same Wi-Fi network, or are on a network configuration (like certain guest networks, or networks with client isolation enabled) that blocks device-to-device communication even though both are nominally "connected" to the same network name
- The API is served over plain HTTP, and Android blocks cleartext traffic by default for apps targeting a sufficiently recent SDK version, regardless of whether you're on emulator or physical device — though this specific issue affects both equally, so wouldn't fully explain an emulator-only-working discrepancy on its own unless something else also differs
- A firewall on the development machine blocking incoming connections on the relevant port from other devices on the network, even though the same machine can freely reach itself via
localhost
The Fix
First, replace localhost or 10.0.2.2 with your development machine's actual local network IP address when targeting a physical device:
const API_URL = 'http://192.168.1.42:3000'; // your machine's actual local IP
Find your machine's current local IP address directly:
# macOS/Linux
ifconfig | grep "inet "
# Windows
ipconfig
Since this IP can change between networks or DHCP lease renewals, consider making it configurable rather than hardcoded, especially if you switch between networks (home, office) regularly during development.
Confirm the physical device and development machine are genuinely on the same network and can actually reach each other — test connectivity directly from the device's own browser first, before assuming it's specifically a React Native or app-level issue:
# From the physical device's mobile browser, visit:
http://192.168.1.42:3000
If this fails even in a plain browser on the device, the issue is confirmed to be network-level (firewall, network isolation, wrong IP) rather than anything specific to your React Native code.
Check your development machine's firewall for rules that might block incoming connections from other devices on the local network, since a firewall commonly allows localhost-originated traffic freely while blocking the same port from external network sources by default:
# macOS - check firewall status
sudo pfctl -s rules
# Windows - check Windows Defender Firewall inbound rules for the relevant port
If the API is served over plain HTTP (common for local development), confirm your Android app allows cleartext traffic, since this specifically affects apps targeting Android API 28+ by default, regardless of emulator versus physical device — though check this even if the emulator currently works, since emulator and physical device network security enforcement can occasionally differ subtly depending on exact configuration:
<!-- android/app/src/main/AndroidManifest.xml -->
<application android:usesCleartextTraffic="true">
Still Not Working?
If you're on a corporate, university, or public network with client isolation enabled (a common security feature on guest and public Wi-Fi that prevents connected devices from directly communicating with each other, even though all are on the same network), no amount of IP or firewall configuration on your development machine resolves this, since the network itself is deliberately blocking device-to-device traffic at the router level. In that specific scenario, using a tool like ngrok to tunnel your local server through a public URL, or switching to a personal hotspot/home network without client isolation for development testing, sidesteps the restriction entirely rather than trying to work around network infrastructure you don't control.