If you are searching for how to set static IP for Raspberry Pi, the first thing you need to know is that the old tutorials are wrong for modern systems. If you are running Raspberry Pi OS "Bookworm" (Debian 12-based, the standard from late 2023 through 2026), the legacy dhcpcd.conf method is deprecated. Editing that file will do absolutely nothing. Bookworm uses NetworkManager by default, meaning you must use the nmcli command-line tool or the nmtui text interface to assign static addresses.
This guide gives you the exact, bench-tested procedure for locking down a static IP on a headless Raspberry Pi 5 or 4, complete with the automated bash script I use for fleet deployments, and the exact error strings you will hit if your subnet math is off.
1. Hardware & Network Planning Matrix
Before touching the terminal, you need a concrete IP plan. Guessing your gateway or subnet mask is the fastest way to lock yourself out of a headless Pi. Below is the reference matrix for a standard Class C home/lab network.
Target Board & Parts List
- Board: Raspberry Pi 5 (8GB) or Raspberry Pi 4 Model B (4GB/8GB)
- OS: Raspberry Pi OS Bookworm (64-bit, Lite or Desktop)
- Network: Cat6 Ethernet cable (preferred for static server assignments) or 2.4GHz/5GHz Wi-Fi
- Debugging: USB-to-TTL serial adapter (CP2102 or PL2303) for headless recovery
Network Interface & IP Allocation Table
NetworkManager separates the interface (e.g., eth0) from the connection profile (e.g., Wired connection 1). You must configure the profile, not the raw interface.
| Parameter | Ethernet Profile (Wired) | Wi-Fi Profile (Wireless) | Notes / Constraints |
|---|---|---|---|
| Connection Name | Wired connection 1 | MyWiFiNetwork | Case-sensitive. Use exactly what nmcli con show outputs. |
| Target Static IP | 192.168.1.50/24 | 192.168.1.51/24 | CIDR notation is mandatory. /24 = 255.255.255.0 subnet mask. |
| Gateway | 192.168.1.1 | 192.168.1.1 | Must be on the same subnet as the static IP. |
| DNS Servers | 1.1.1.1, 8.8.8.8 | 1.1.1.1, 8.8.8.8 | Comma-separated, no spaces. |
| Method | manual | manual | Tells NetworkManager to ignore DHCP offers. |
Headless Debugging: UART Pin Mapping
If you mistype your gateway and lose SSH access, you need a physical backdoor. Here is the exact pin mapping to connect a USB-TTL serial adapter to the Pi's GPIO header for direct console access.
| Pi GPIO Pin (Physical) | BCM Function | USB-TTL Adapter Pin | Wiring Rule |
|---|---|---|---|
| Pin 6 | GND | GND | Common ground is mandatory for logic levels. |
| Pin 8 | GPIO 14 (TXD) | RXD (Receive) | TX always connects to RX (cross-over). |
| Pin 10 | GPIO 15 (RXD) | TXD (Transmit) | RX always connects to TX (cross-over). |
Note: Ensure your USB-TTL adapter is set to 3.3V logic. Feeding 5V into Pin 10 will fry the Pi's UART controller.
2. The Right Way: Setting Static IP via nmcli
Open your SSH session or serial terminal. We are going to modify the default Ethernet connection profile. Do not try to create a new profile from scratch unless you are bonding interfaces; modifying the existing one preserves your link-state rules.
- Identify your active connections:
nmcli connection show
Look under the "NAME" column. For a fresh Pi OS install on Ethernet, it is almost alwaysWired connection 1. - Assign the Static IP, Gateway, and DNS:
nmcli connection modify "Wired connection 1" ipv4.addresses 192.168.1.50/24 ipv4.gateway 192.168.1.1 ipv4.dns "1.1.1.1,8.8.8.8" ipv4.method manual
Crucial: The quotes around the connection name are required if it contains spaces. - Apply the changes by bouncing the interface:
nmcli connection up "Wired connection 1"
Your SSH session will freeze and disconnect immediately because your IP address just changed. Reconnect using the new static IP. - Verify the assignment:
ip -4 addr show eth0
You should seeinet 192.168.1.50/24in the output.
NetworkManager assigns an
autoconnect-priority to profiles. If you have multiple wired profiles, ensure your static profile has the highest priority so it boots first: nmcli con mod "Wired connection 1" connection.autoconnect-priority 10.
3. Automated Setup & Verification Script
When provisioning multiple Pis for a sensor array or home lab cluster, typing nmcli flags manually invites typos. Below is a complete, production-ready bash script. It targets Raspberry Pi OS Bookworm (64-bit) and includes error handling to verify that nmcli exists, the connection profile is valid, and the gateway is reachable post-assignment.
#!/bin/bash
# Target: Raspberry Pi 5 / 4 (Raspberry Pi OS Bookworm 64-bit)
# Purpose: Set static IP via NetworkManager (nmcli) with error handling
set -e # Exit immediately if a command exits with a non-zero status
# --- CONFIGURATION VARIABLES ---
CONN_NAME="Wired connection 1"
STATIC_IP="192.168.1.50/24"
GATEWAY="192.168.1.1"
DNS="1.1.1.1,8.8.8.8"
# --- PRE-FLIGHT CHECKS ---
# 1. Verify NetworkManager is the active network daemon
if ! command -v nmcli &> /dev/null; then
echo "FATAL: nmcli not found. Are you on Bullseye or older using dhcpcd?"
exit 1
fi
# 2. Check if the target connection profile actually exists
if ! nmcli connection show "$CONN_NAME" &> /dev/null; then
echo "ERROR: Connection '$CONN_NAME' not found."
echo "Run 'nmcli con show' to find your exact interface profile name."
exit 1
fi
# --- APPLY CONFIGURATION ---
echo "Applying static IP configuration to '$CONN_NAME'..."
nmcli connection modify "$CONN_NAME" \
ipv4.addresses "$STATIC_IP" \
ipv4.gateway "$GATEWAY" \
ipv4.dns "$DNS" \
ipv4.method manual
echo "Restarting connection to apply changes..."
# We use 'up' which implicitly brings down the previous state
nmcli connection up "$CONN_NAME" || echo "WARNING: Connection dropped (expected if SSH IP changed)."
# --- POST-FLIGHT VERIFICATION ---
# Wait 3 seconds for the link to negotiate and ARP to resolve
sleep 3
if ping -c 3 -W 2 "$GATEWAY" &> /dev/null; then
echo "SUCCESS: Gateway reachable at $GATEWAY. Static IP $STATIC_IP is live."
else
echo "WARNING: Cannot ping gateway. Check subnet mask, physical link, and gateway IP."
exit 1
fi
4. Debugging: Exact Error Strings and Fixes
NetworkManager is notoriously pedantic about syntax. If your setup fails, you will likely hit one of these exact error strings. Here is the ranked cause list and the fix for each.
Error 1: Error: unknown connection 'eth0'.
- Cause: You are treating
nmclilike the oldifupdownsystem.eth0is the hardware interface name, butnmcli connection modifyexpects the Connection Name (the profile). - Fix: Run
nmcli con showand use the value in the NAME column (e.g.,"Wired connection 1").
Error 2: Error: Failed to add 'Wired connection 1' connection: connection already exists.
- Cause: You accidentally used
nmcli connection addinstead ofnmcli connection modify. Theaddcommand tries to create a brand new profile from scratch. - Fix: Use
modifyto edit existing profiles. If you truly want a fresh profile, delete the old one first:nmcli con delete "Wired connection 1".
Error 3: ping: connect: Network is unreachable
- Cause: Subnet mismatch. Your static IP and your gateway do not share the same network space based on your CIDR mask. For example, setting IP
192.168.1.50/24but gateway192.168.0.1. - Fix: Verify your router's actual subnet. Most home routers use
/24(255.255.255.0), meaning the first three octets of the IP and Gateway must match exactly.
5. First Three Things to Check When It Fails
If you applied the settings, rebooted, and cannot reach the Pi via SSH or ping, do not immediately reflash the SD card. Run through this physical and logical checklist:
- Check for IP Conflicts on the LAN: If you assigned
192.168.1.50but your router's DHCP pool hasn't excluded that address, the router may have handed it to your phone or a smart TV. The resulting ARP conflict will drop the Pi's packets. Fix: Log into your router and shrink the DHCP pool (e.g., .100 to .200) or bind the Pi's MAC address to the static IP in the router's DHCP reservation table. - Verify the Physical Link State: Run
nmcli device statusvia your UART serial console. Ifeth0shows asdisconnectedorunavailable, NetworkManager refuses to apply the IP profile to a dead link. Check your Cat6 cable and switch port LEDs. - Inspect the Routing Table: Run
ip route. If thedefault vialine is missing or points to the wrong gateway, your Pi can talk to local devices but cannot route to the internet or external subnets. Re-apply theipv4.gatewayparameter vianmcli.
6. Extending and Simplifying the Build
Depending on your end goal, a manual static IP on the Pi itself might be the wrong architectural choice. Here is how to simplify or extend this setup based on real-world deployment scenarios.
Simplify: Use DHCP Reservations (The "No-Touch" Method)
If you are deploying a Pi in a home environment where you control the router, do not set the static IP on the Pi. Leave the Pi on DHCP (ipv4.method auto). Instead, log into your router (pfSense, UniFi, or standard consumer Asus/Netgear) and create a DHCP Reservation binding the Pi's MAC address to 192.168.1.50.
Why? If you move the Pi to a different network (e.g., a friend's house or a different VLAN), a hardcoded static IP will instantly brick your network access. DHCP reservations keep the Pi portable while guaranteeing the IP never changes on your home LAN.
Extend: mDNS and Avahi for Headless Discovery
If you hate memorizing IP addresses entirely, ensure the avahi-daemon package is installed and running. This enables multicast DNS (mDNS). You can then SSH into your Pi using its hostname followed by .local, regardless of what IP the DHCP server or NetworkManager assigns it:
ssh pi@raspberrypi.local
This is the standard protocol used by Apple (Bonjour) and modern Linux distributions for local network discovery, completely bypassing the need to check your router's client list for the Pi's current IP.
Authoritative References:
For deeper reading on the transition from dhcpcd to NetworkManager in Raspberry Pi OS, consult the official Raspberry Pi Network Configuration documentation. For advanced nmcli syntax and property flags, refer to the NetworkManager nmcli manual.






