The most reliable way to configure a Raspberry Pi as hotspot on modern Raspberry Pi OS (Bookworm and later) is using NetworkManager via the nmcli command-line tool. The legacy method of manually editing hostapd.conf and dnsmasq is deprecated, prone to boot-race conditions, and will fail on current OS images. This guide provides the exact nmcli commands, a Python GPIO monitoring script, and a debugging framework for when the interface drops.
The Verdict: Which Board Variant to Pick
Not every Pi is suited for 24/7 access point duty. Thermal throttling and Wi-Fi chip capabilities dictate your choice. Use this decision path to select your board:
| Criteria | Pi Zero 2 W | Pi 4 Model B (4GB) | Pi 5 (8GB) |
|---|---|---|---|
| Wi-Fi Band | 2.4GHz only | Dual-band (2.4 / 5GHz) | Dual-band (2.4 / 5GHz) |
| Thermal Profile (Passive) | Excellent (low draw) | Good (requires basic heatsink) | Poor (requires Active Cooler) |
| Routing Overhead | High (CPU bottleneck) | Low | Negligible |
| Approx. Cost (2026) | $15 - $20 | $55 | $80+ |
Parts List and GPIO Pin Mapping
This build targets the Raspberry Pi 4 Model B (4GB) running Raspberry Pi OS Bookworm (64-bit, Lite). The code and pinouts below are fully compatible with the Pi 5 if you opt for that route.
Bill of Materials
- Board: Raspberry Pi 4 Model B (4GB RAM)
- Storage: SanDisk Extreme 32GB microSD (A2 rating required for Bookworm's I/O patterns)
- Power: Official Raspberry Pi 27W USB-C PD Power Supply (prevents brownout warnings under Wi-Fi TX load)
- Indicators: 2x 5mm LEDs (Green/Red), 2x 330Ω resistors, half-size breadboard
GPIO Pin Mapping for Status Monitor
We will use two GPIO pins to drive physical LEDs, giving you a visual diagnostic of the hotspot state without needing to SSH in.
| Function | GPIO (BCM) | Physical Pin | Component |
|---|---|---|---|
| Hotspot Active (Green) | GPIO 17 | Pin 11 | Green LED + 330Ω to GND |
| Hotspot Down (Red) | GPIO 27 | Pin 13 | Red LED + 330Ω to GND |
| Ground Reference | GND | Pin 9 | Common ground for LEDs |
Step-by-Step Hotspot Configuration
Forget /etc/hostapd/hostapd.conf. On Bookworm, NetworkManager owns the Wi-Fi stack. Run these commands exactly as written in your SSH terminal.
- Update the system and install prerequisites:
sudo apt update && sudo apt upgrade -y sudo apt install network-manager python3-gpiozero -y - Create the Wi-Fi connection profile:
sudo nmcli connection add type wifi ifname wlan0 con-name "PiHotspot" autoconnect yes ssid "FluxNet_5G" - Set the connection to Access Point mode and configure IP sharing:
sudo nmcli connection modify "PiHotspot" 802-11-wireless.mode ap 802-11-wireless.band a ipv4.method sharedNote:
band aforces 5GHz. Change toband bgif you strictly need 2.4GHz for legacy IoT devices. - Apply WPA2 security:
sudo nmcli connection modify "PiHotspot" wifi-sec.key-mgmt wpa-psk wifi-sec.psk "YourSecurePassword123!" - Bring the interface up:
sudo nmcli connection up "PiHotspot" - Verify the state:
nmcli connection show --activeYou should see
PiHotspotlisted withwifias the type andwlan0as the device.
ipv4.method shared automatically spins up an internal DHCP server (dnsmasq under the hood) and configures iptables for NAT routing. You do not need to manually configure IP forwarding in sysctl.conf.
Python Status Monitor Script
Headless access points are frustrating when they drop offline. This Python script polls NetworkManager via nmcli and updates the physical GPIO LEDs. It includes robust error handling for interface drops.
#!/usr/bin/env python3
import subprocess
import time
import sys
from gpiozero import LED
# --- PIN DEFINITIONS ---
PIN_GREEN = 17 # Physical Pin 11 (Hotspot Active)
PIN_RED = 27 # Physical Pin 13 (Hotspot Down/Error)
green_led = LED(PIN_GREEN)
red_led = LED(PIN_RED)
def check_hotspot_status():
"""Queries NetworkManager for the PiHotspot connection state."""
try:
# Run nmcli to get the state of our specific connection
result = subprocess.run(
['nmcli', '-g', 'GENERAL.STATE', 'connection', 'show', 'PiHotspot'],
capture_output=True, text check=True, timeout=5
)
state = result.stdout.strip()
if 'activated' in state.lower():
return True
return False
except subprocess.CalledProcessError:
# Connection profile missing or nmcli failed
return False
except subprocess.TimeoutExpired:
# NetworkManager is hung
return False
except Exception as e:
print(f"Unexpected error querying nmcli: {e}", file=sys.stderr)
return False
def main():
print("Starting Pi Hotspot GPIO Monitor...")
try:
while True:
is_active = check_hotspot_status()
if is_active:
green_led.on()
red_led.off()
else:
green_led.off()
red_led.blink(on_time=0.5, off_time=0.5, background=False)
# Note: background=False blocks, so we use a manual loop for blink effect in a real daemon,
# but for this simple script, we'll just do a solid red to avoid blocking the sleep.
red_led.on()
time.sleep(10) # Poll every 10 seconds
except KeyboardInterrupt:
print("\nMonitor stopped by user.")
finally:
green_led.off()
red_led.off()
print("LEDs cleaned up.")
if __name__ == '__main__':
main()
Save this as ap_monitor.py and run it via sudo python3 ap_monitor.py. For persistence, wrap it in a systemd service.
Debugging: Exact Error Strings and Ranked Causes
When configuring a Raspberry Pi as hotspot, NetworkManager will throw specific errors if the hardware or stack is misconfigured. Here are the first three things to check, mapped to their exact terminal outputs.
1. "No suitable device found"
Exact Error String: Error: Connection activation failed: No suitable device found for this connection
Ranked Causes:
- RFKill Soft Block: The Wi-Fi chip is disabled at the kernel level. Fix: Run
sudo rfkill unblock wifi. - Interface Renaming: You plugged in a USB Wi-Fi dongle, and the internal chip became
wlan1. Fix: Runiwconfigto verify the internal chip name, then modify the connection:sudo nmcli connection modify "PiHotspot" connection.interface-name wlan0. - Country Code Missing: The 5GHz radio refuses to transmit without a regulatory domain. Fix: Run
sudo raspi-config-> Localisation Options -> WLAN Country, and set it to your region.
2. "Secrets were required, but no secrets were provided"
Exact Error String: Error: Connection activation failed: Secrets were required, but no secrets were provided.
Ranked Causes:
- Password Too Short: WPA2 requires a minimum of 8 characters. If your
wifi-sec.pskwas shorter, NetworkManager silently drops it during creation and fails on activation. Fix: Re-run thenmcli modifycommand with a 12+ character password. - Missing Key Management: You forgot to set
wifi-sec.key-mgmt wpa-psk. Fix: Add it via the modify command.
3. "hostapd.service: Failed with result 'exit-code'"
Exact Error String: hostapd.service: Failed with result 'exit-code' (Seen in journalctl -xe)
Ranked Causes:
- Conflicting Legacy Configs: You followed a 2021 tutorial and manually installed
hostapdanddnsmasq. NetworkManager and standalone hostapd cannot both controlwlan0. Fix:sudo apt purge hostapd dnsmasqand reboot.
Extending or Simplifying the Build
Once your baseline hotspot is stable, you have two distinct paths depending on your network goals.
Extension: Add Network-Wide Ad Blocking (Pi-hole)
Because NetworkManager's shared method acts as a DHCP server, you can intercept DNS requests to run Pi-hole.
- Install Pi-hole:
curl -sSL https://install.pi-hole.net | bash - During setup, select
wlan0as the interface. - Force NetworkManager to hand out the Pi's IP as the DNS server:
sudo nmcli connection modify "PiHotspot" ipv4.dns "192.168.4.1"(assuming default shared subnet). - Restart the connection:
sudo nmcli connection up "PiHotspot".
Simplification: Bridge Mode (No NAT Routing)
If you don't want the Pi to act as a router creating a separate subnet, but rather just a wireless bridge to your main router's LAN:
- Delete the shared connection:
sudo nmcli connection delete "PiHotspot" - Create a bridge:
sudo nmcli connection add type bridge con-name "br0" ifname br0 - Bridge the Ethernet and Wi-Fi: Add
wlan0andeth0as slaves tobr0usingnmcli connection add type bridge-slave. - Warning: Bridging Wi-Fi to Ethernet requires the Wi-Fi chip to support 4-address mode (WDS), which the internal Pi Wi-Fi chips struggle with. If you need a true bridge, buy a TP-Link Archer T3U Plus USB Wi-Fi adapter which supports monitor/bridge modes reliably on Linux.
By sticking to NetworkManager and ditching legacy hostapd configs, your Raspberry Pi hotspot will survive OS upgrades, reboot cleanly, and route traffic at line speed without throwing cryptic DHCP race errors.






