If you are searching for how to set static IP on Raspberry Pi 5, the first thing you need to know is that almost every tutorial written before late 2023 is wrong for your board. The Raspberry Pi 5 ships with Raspberry Pi OS Bookworm (Debian 12), which completely removed the dhcpcd daemon in favor of NetworkManager. If you try to edit /etc/dhcpcd.conf, you will either get a blank file or break your network stack.
The direct answer: To set a static IP on a headless Pi 5, use the nmcli command-line tool to modify the active NetworkManager profile. For a desktop environment, use the nm-connection-editor GUI. However, for 90% of home lab deployments, the most robust method is actually setting a DHCP reservation on your router rather than touching the Pi's OS configuration.
The Bookworm Shift: Why Old Static IP Tutorials Fail
In previous OS versions (Bullseye and earlier), networking was handled by dhcpcd. You would append a few lines to /etc/dhcpcd.conf, reboot, and your Pi would hold its address. With the Pi 5 and Bookworm, Raspberry Pi transitioned to NetworkManager to align with upstream Debian standards and improve support for complex routing, VPNs, and cellular modems.
NetworkManager uses connection profiles rather than interface names. This means you don't assign an IP to eth0; you assign it to a profile named "Wired connection 1". Understanding this distinction is the key to avoiding the most common configuration loops.
Decision Path: Which Method Should You Use?
| Your Scenario | Environment | Method to Use |
|---|---|---|
| Headless Pi in a home network with a standard router | Home Lab / Maker | Router DHCP Reservation (Simplifies Pi config) |
| Headless Pi on an isolated switch or direct-to-laptop | Industrial / Kiosk | nmcli (CLI) (Required, no router present) |
| Pi 5 connected to a monitor, mouse, and keyboard | Desktop Workstation | nm-connection-editor (GUI) |
Terminating Default Pick: If you have access to your router's admin panel, use a Router DHCP Reservation mapped to the Pi's MAC address. It survives OS reimaging and prevents IP conflicts. If you are deploying a headless kiosk or an isolated sensor node where no router exists, use the nmcli method detailed below.
Hardware & Interface Mapping
While setting an IP is a software task, verifying network health on a headless Pi 5 often requires hardware feedback. Below is the parts list and pin mapping for a physical network-status indicator, which we will drive with Python later in this guide.
Parts List
- Board: Raspberry Pi 5 (8GB variant, SKU SC1148) running Raspberry Pi OS Bookworm 64-bit.
- Network: CAT6 Ethernet cable (for Gigabit stability) or Wi-Fi 5 (dual-band).
- Indicators: 2x 5mm LEDs (Green for OK, Red for Fault), 2x 330Ω through-hole resistors.
- Wiring: Breadboard and female-to-male jumper wires.
Hardware-to-Network Interface & Status Pin Mapping
| Logical Interface | NetworkManager Profile Name (Default) | Physical Hardware | GPIO Pin Mapping (Status LEDs) |
|---|---|---|---|
eth0 | Wired connection 1 | Pi 5 Gigabit Ethernet Jack | GPIO 17 (Pin 11) -> Green LED (Link OK) |
wlan0 | SSID_Name (e.g., HomeWiFi) | Pi 5 onboard Wi-Fi/BT module | GPIO 27 (Pin 13) -> Red LED (IP Fault/Fallback) |
| N/A | N/A | Common Ground | GND (Pin 9) -> LED Cathodes |
Step-by-Step: Setting the Static IP via nmcli
This procedure assumes you are connected via SSH or a direct serial console. We will configure the Ethernet interface. Ensure you know your network's subnet (usually /24 or 255.255.255.0) and gateway before starting.
Verify Dead / Safety Check: If you are doing this over SSH and make a typo in the gateway or subnet mask, you will lock yourself out of the Pi. If you don't have physical access to pull the SD card or attach a monitor, use tmux or screen, or set a cron job to revert the network settings after 5 minutes while you test.
- Identify your active connection profile name.
Run:nmcli connection show
Look under the "NAME" column. For Ethernet, it is typicallyWired connection 1. Do not use the "DEVICE" column name (eth0) for modification commands. - Assign the static IP address and subnet mask.
Run:sudo nmcli connection modify "Wired connection 1" ipv4.addresses 192.168.1.50/24
Note: NetworkManager requires CIDR notation. Use/24for a standard home subnet, not255.255.255.0. - Set the default gateway.
Run:sudo nmcli connection modify "Wired connection 1" ipv4.gateway 192.168.1.1 - Configure DNS servers.
Run:sudo nmcli connection modify "Wired connection 1" ipv4.dns "1.1.1.1 8.8.8.8"
Separate multiple DNS servers with a space, not a comma. - Switch the IPv4 method from DHCP to manual.
Run:sudo nmcli connection modify "Wired connection 1" ipv4.method manual - Apply the changes by restarting the connection.
Run:sudo nmcli connection up "Wired connection 1" - Verify the assignment.
Run:ip -4 addr show eth0. You should seeinet 192.168.1.50/24listed.
Debugging: Exact Error Strings and Ranked Causes
When configuring NetworkManager via CLI, typos and legacy assumptions trigger specific errors. Here are the first three things to check when your connection fails to apply, mapped to the exact error strings you will see.
Error 1: Error: unknown connection 'eth0'
Ranked Causes:
- Using device name instead of profile name: You typed
nmcli connection modify eth0. NetworkManager manages profiles, not raw interfaces. Fix: Use"Wired connection 1". - Profile was deleted or renamed: Run
nmcli connection showto verify the exact string in the NAME column.
Error 2: bash: /etc/dhcpcd.conf: No such file or directory
Ranked Causes:
- Following outdated tutorials: You are on Bookworm (Debian 12) or later.
dhcpcdis uninstalled by default. Fix: Stop editing text files and usenmclias shown above. - Custom minimal OS image: If you are using DietPi or a custom Yocto build, networking might be handled by
systemd-networkd. Check withsystemctl status systemd-networkd.
Error 3: RTNETLINK answers: File exists
Ranked Causes:
- Duplicate IP routing: You manually added a route using the
ip routecommand, and now NetworkManager is trying to add the same route upon bringing the interface up. Fix: Flush the manual routes withsudo ip route flush dev eth0before runningnmcli connection up. - IP Conflict on the LAN: Another device already holds 192.168.1.50. While this usually results in a silent failure or ARP warnings, strict network namespaces can throw routing errors. Fix: Ping the target IP from another machine before assigning it.
Python Network Verification Script (GPIO Feedback)
To ensure your Pi 5 maintains its static IP and hasn't fallen back to an APIPA address (169.254.x.x) after a network hiccup, we can use a Python script. This script queries the network state and drives the GPIO pins mapped in our hardware table.
This code targets the Raspberry Pi 5 8GB running Bookworm 64-bit. It uses the pre-installed gpiozero library and standard Python socket modules to avoid pip dependency issues.
#!/usr/bin/env python3
"""
Pi 5 Network Status Monitor
Targets: Raspberry Pi 5 (Bookworm 64-bit)
Hardware: Green LED on GPIO 17, Red LED on GPIO 27
"""
import socket
import subprocess
import time
import sys
from gpiozero import LED
# --- PIN DEFINITIONS ---
PIN_LED_OK = 17 # Green LED: Valid Static/DHCP IP assigned
PIN_LED_FAULT = 27 # Red LED: Fallback IP (169.254.x.x) or disconnected
# Initialize GPIO
green_led = LED(PIN_LED_OK)
red_led = LED(PIN_LED_FAULT)
def get_ip_address(interface='eth0'):
"""Fetches the IPv4 address of the specified interface using iproute2."""
try:
# Using subprocess to avoid deprecated netifaces library issues on Bookworm
cmd = f"ip -4 addr show {interface} | grep -oP '(?<=inet\s)\d+(\.\d+){{3}}'"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, check=True)
ip = result.stdout.strip()
return ip if ip else None
except subprocess.CalledProcessError:
return None
def check_network_health(ip_addr):
"""Returns True if IP is valid (not APIPA/fallback), False otherwise."""
if not ip_addr:
return False
# APIPA / Link-Local fallback range indicates DHCP/Static failure
if ip_addr.startswith("169.254."):
return False
return True
def main():
print("Starting Pi 5 Network Monitor...")
print(f"Monitoring interface: eth0")
try:
while True:
current_ip = get_ip_address('eth0')
is_healthy = check_network_health(current_ip)
if is_healthy:
green_led.on()
red_led.off()
print(f"[OK] Link stable. IP: {current_ip}")
else:
green_led.off()
red_led.blink(on_time=0.5, off_time=0.5)
print(f"[FAULT] Network degraded. IP: {current_ip or 'None'}")
time.sleep(10) # Poll every 10 seconds
except KeyboardInterrupt:
print("\nMonitor stopped by user.")
except Exception as e:
print(f"Critical Error: {e}")
red_led.on() # Solid red on script crash
finally:
# Clean up GPIO states on exit
green_led.off()
red_led.off()
if __name__ == "__main__":
main()
First three things to check when this script fails to run:
- GPIO Permissions: Bookworm handles GPIO via the
gpiogroup, not root. Ensure your user is in the group:sudo usermod -aG gpio $USER, then log out and back in. - Interface Name Mismatch: If you are testing over Wi-Fi, change
get_ip_address('eth0')toget_ip_address('wlan0'). - Missing iproute2: The script relies on the
ipcommand. If you stripped down your OS, install it viasudo apt install iproute2.
Extending and Simplifying the Build
How to Simplify: The Router DHCP Reservation
If you are building a home automation server, a Pi-hole, or a media center, do not set the static IP on the Pi itself. Instead, log into your router (e.g., UniFi, pfSense, or standard ISP gateway), find the DHCP lease table, locate the Pi 5's MAC address, and assign a fixed IP there. This keeps the Pi's OS configuration default (DHCP), meaning if you ever swap SD cards or reinstall the OS, your network configuration survives intact without needing to re-run nmcli commands.
How to Extend: Ansible and Fleet Management
If you are deploying multiple Pi 5 nodes (e.g., a Kubernetes cluster or a sensor array), manually running nmcli via SSH does not scale. Extend this build by using Ansible's community.general.nmcli module. You can define your static IP matrix in a YAML inventory file and push the NetworkManager profiles to 50 Pi 5 boards simultaneously, complete with rollback handlers if the gateway ping fails.
For advanced edge deployments where the Pi 5 is connected to multiple VLANs via a managed switch, you can extend the nmcli configuration to include 802.1Q VLAN tagging directly on the "Wired connection 1" profile, allowing a single physical Gigabit port to service isolated IoT and management networks concurrently.






