If you are trying to configure wifi on raspberry pi hardware running Raspberry Pi OS Bookworm (Debian 12) or newer, the rules have changed. The legacy wpa_supplicant.conf method is dead. The modern Pi OS relies entirely on NetworkManager, managed via the nmcli command-line tool or the raspi-config utility.
This guide provides the exact CLI steps, a Python automation script with GPIO hardware fallback, and a debugging matrix for the specific error strings NetworkManager throws when a connection fails. We are targeting the Raspberry Pi 5 (4GB/8GB) and Raspberry Pi 4 Model B running the 64-bit Bookworm release.
The NetworkManager Shift: Why Old Guides Fail
For years, the standard headless setup trick was dropping a wpa_supplicant.conf file into the /boot (now /boot/firmware) partition. This no longer works on Bookworm. NetworkManager does not read that file. If you attempt it, your Pi will boot, but the wireless interface (wlan0) will remain unconfigured.
/etc/NetworkManager/system-connections/.
Hardware BOM and GPIO Pin Mapping
When deploying a Pi in an embedded enclosure, you need a physical way to verify network status or force a radio reset without SSH access. Below is the parts list and pin mapping for a hardware WiFi status indicator and reset button.
| Component | Spec / Variant | BCM GPIO | Physical Pin |
|---|---|---|---|
| Main Board | Raspberry Pi 5 (8GB) or Pi 4B | N/A | N/A |
| Power Supply | Official 27W USB-C PD (Pi 5) | N/A | N/A |
| Status LED | 5mm Green LED + 330Ω Resistor | GPIO 27 | Pin 13 |
| Reset Button | 6x6mm Tactile Switch (NO) | GPIO 17 | Pin 11 |
| Ground Reference | Common Ground Rail | GND | Pin 9 |
CLI Steps to Configure WiFi on Raspberry Pi
If your Pi is already booted and connected via Ethernet or a serial console, use nmcli to configure the wireless connection. This is the definitive method for Debian 12+.
- Scan for available networks:
sudo nmcli device wifi list
Note: If the list is empty, ensure your regulatory domain is set (see Debugging below). - Add and activate the connection:
sudo nmcli connection add type wifi ifname wlan0 con-name "MyPiNet" ssid "YourSSID"
sudo nmcli connection modify "MyPiNet" wifi-sec.key-mgmt wpa-psk wifi-sec.psk "YourPassword"
sudo nmcli connection up "MyPiNet" - Set connection priority (auto-connect):
sudo nmcli connection modify "MyPiNet" connection.autoconnect yes connection.autoconnect-priority 10 - Verify the IP address:
ip -4 addr show wlan0
Python Automation: NetworkManager + GPIO Fallback
In embedded deployments, network drops happen. The following Python script uses the gpiozero library to monitor a physical button on GPIO 17. When pressed, it forces NetworkManager to tear down and rebuild the WiFi connection, while a status LED on GPIO 27 indicates link state.
import subprocess
import sys
import time
import logging
from gpiozero import Button, LED
# --- Hardware Pin Definitions ---
WIFI_RESET_PIN = 17 # Physical Pin 11
STATUS_LED_PIN = 27 # Physical Pin 13
# --- Network Configuration ---
CONNECTION_NAME = "MyPiNet"
POLL_INTERVAL = 5 # Seconds between status checks
# Initialize Hardware
reset_btn = Button(WIFI_RESET_PIN, pull_up=True, bounce_time=0.2)
status_led = LED(STATUS_LED_PIN)
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def check_wifi_status():
"""Returns True if wlan0 has an active IP address."""
try:
result = subprocess.run(
['ip', '-4', 'addr', 'show', 'wlan0'],
capture_output=True, text=True, check=True
)
return 'inet ' in result.stdout
except subprocess.CalledProcessError:
return False
def force_wifi_reset():
"""Tears down and brings up the NetworkManager connection."""
logging.warning("Hardware reset triggered. Restarting WiFi interface...")
status_led.blink(on_time=0.2, off_time=0.2)
try:
# Bring connection down
subprocess.run(
['sudo', 'nmcli', 'connection', 'down', CONNECTION_NAME],
capture_output=True, text=True, check=True
)
time.sleep(2)
# Bring connection up
subprocess.run(
['sudo', 'nmcli', 'connection', 'up', CONNECTION_NAME],
capture_output=True, text=True, check=True
)
logging.info("NetworkManager successfully restarted connection.")
except subprocess.CalledProcessError as e:
logging.error(f"nmcli command failed: {e.stderr.strip()}")
finally:
status_led.stop_blinking()
# Bind hardware interrupt
reset_btn.when_pressed = force_wifi_reset
if __name__ == "__main__":
logging.info(f"WiFi Monitor started. Reset on GPIO {WIFI_RESET_PIN}.")
try:
while True:
if check_wifi_status():
status_led.on()
else:
status_led.off()
logging.warning("wlan0 lacks an IP address.")
time.sleep(POLL_INTERVAL)
except KeyboardInterrupt:
logging.info("Shutting down monitor.")
sys.exit(0)
Debugging Matrix: Exact Error Strings and Fixes
When you configure wifi on raspberry pi hardware via CLI, NetworkManager is highly verbose about failures. Here are the exact error strings you will encounter, ranked by frequency, and how to fix them.
| Exact Error String | Root Cause | Fix / Command |
|---|---|---|
Error: Connection activation failed: (7) Secrets were required, but not provided. |
The PSK (password) was not saved correctly to the keyring, or the key management type is mismatched (e.g., WPA3 vs WPA2). | Re-apply the password explicitly:sudo nmcli connection modify "MyPiNet" wifi-sec.psk "YourPassword" |
Error: No network with SSID 'YourSSID' found. |
1. Typo in SSID (case-sensitive). 2. Router is using a 5GHz DFS channel (100+) and the Pi lacks a regulatory domain. 3. AP is set to 6GHz (WiFi 6E) which Pi 4/5 hardware does not support. |
Set the country code to unlock DFS channels:sudo raspi-config -> Localisation Options -> WLAN Country. |
Warning: password for '802-11-wireless-security' not given in 'passwd-file' nor provided via 'ask' |
You used the one-line nmcli device wifi connect syntax but omitted the password flag or used the wrong syntax for Bookworm. |
Use the two-step connection add and connection modify syntax shown in the CLI steps above. |
device (wlan0): state change: config -> failed (reason 'supplicant-failed') |
Power supply brownout causing the WiFi chip to drop off the SDIO bus, or RF interference from an unshielded HDMI cable. | Verify PSU voltage (vcgencmd get_throttled). Use an official power supply and shielded HDMI cables. |
1. Regulatory Domain: Run
sudo iw reg get. If it says country 00: DFS-UNSET, your Pi will refuse to connect to many 5GHz networks. Set it via raspi-config.2. Case Sensitivity: NetworkManager treats
MyNetwork and mynetwork as entirely different SSIDs. Check your router's exact broadcast name.3. Power Throttling: Run
vcgencmd get_throttled. If it returns 0x50000 or similar, your Pi is experiencing undervoltage, which disproportionately kills the WiFi radio first.
Frequently Asked Questions
How do I configure wifi on raspberry pi headless without a monitor in 2026?
Because the wpa_supplicant.conf trick is deprecated in Bookworm, you must use the Raspberry Pi Imager desktop application. Select your OS, click the gear icon (Advanced Options), check "Configure wireless LAN", and enter your SSID and password. The Imager securely writes the NetworkManager configuration files directly to the root filesystem before the first boot. If you are flashing via CLI using dd or balenaEtcher, you must pre-create the /etc/NetworkManager/system-connections/ directory structure on the ext4 partition before inserting the SD card into the Pi.
Why is my wpa_supplicant.conf file not working on Raspberry Pi OS Bookworm?
Raspberry Pi OS transitioned to NetworkManager as the default network stack starting with the Bookworm release. The wpa_supplicant daemon is no longer running by default, and the boot sequence does not parse the /boot/firmware/wpa_supplicant.conf file. Any tutorial instructing you to use this method is outdated. You must use nmcli, the raspi-config tool, or the Raspberry Pi Imager's advanced settings to configure wireless networks on modern Pi OS versions.
How can I set a static IP when I configure wifi on raspberry pi?
NetworkManager handles static IP assignments natively, replacing the old dhcpcd.conf method. To set a static IP of 192.168.1.50 with a gateway of 192.168.1.1 and DNS of 1.1.1.1, use the following commands:
sudo nmcli connection modify "MyPiNet" ipv4.addresses 192.168.1.50/24
sudo nmcli connection modify "MyPiNet" ipv4.gateway 192.168.1.1
sudo nmcli connection modify "MyPiNet" ipv4.dns "1.1.1.1 8.8.8.8"
sudo nmcli connection modify "MyPiNet" ipv4.method manual
sudo nmcli connection up "MyPiNet"
How can I extend or simplify this embedded build?
To simplify: Remove the Python script entirely and rely purely on NetworkManager's built-in connection.autoconnect-priority and connection.autoconnect-retries flags. NetworkManager will automatically handle basic dropouts and reconnections in the background.
To extend: Add an MQTT client to the Python script. When the hardware button resets the WiFi, publish a telemetry message to your home automation broker (e.g., Home Assistant) logging the network drop event, the timestamp, and the RSSI signal strength prior to the failure. This turns a simple hardware reset into a powerful network-monitoring edge node.
References: Raspberry Pi Official Configuration Documentation, NetworkManager nmcli Reference Manual.






