Troubleshooting

ifconfig: command not found — plus netstat, ping and the ip replacements

ifconfig and netstat live in the old net-tools package, ping in iputils. Install them on any distro, or use ip and ss, which every modern server has.

Published ~7 min read

ifconfig: command not found — and the same error for netstat — means the old net-tools package is not installed; current distributions no longer include it by default. The quick fix is to use ip a instead of ifconfig and ss -tulpn instead of netstat, which come from iproute2 and are already on every modern Linux. If a script genuinely needs the old names, install net-tools — and iputils-ping for ping.

quick fix
# modern replacements — already installed
ip a                 # instead of ifconfig
ss -tulpn            # instead of netstat -tulpn

# or install the legacy tools
sudo apt install -y net-tools     # Debian, Ubuntu
sudo dnf install -y net-tools     # Rocky, Alma, RHEL
apk add net-tools                 # Alpine

Why is ifconfig missing?

ifconfig, netstat, route and arp all come from net-tools, a package that has been in maintenance mode for a long time. It never learned about a lot of what the kernel can do — multiple addresses on one interface, policy routing, modern tunnels — so the distributions moved to iproute2 (the ip and ss commands) and stopped installing net-tools by default. Debian, Ubuntu, Fedora, Rocky and Alma minimal images, and nearly every container base, ship without it. Nothing is broken; the tool was simply left out.

How do I install net-tools?

One package brings back ifconfig, netstat, route, arp and mii-tool. Logged in as root in a container? Drop the sudo.

Debian · Ubuntu
sudo apt update
sudo apt install -y net-tools
Rocky · Alma · RHEL · Fedora
sudo dnf install -y net-tools
Alpine
apk add net-tools

On every distribution ifconfig, route and arp land in an sbin directory, while netstat goes into bin. That is why netstat can work for a normal user while ifconfig still is not found. If the command is missing after installing, re-read the PATH note above, or run hash -r to clear a stale shell lookup.

What are the ip and ss equivalents?

Learning the two replacements is a better use of your time than reinstalling the old package, because iproute2 is the one you will find everywhere. The translation is mechanical:

net-tools → iproute2
ifconfig                   ->  ip a          (or: ip -br a, one line per interface)
ifconfig eth0              ->  ip addr show dev eth0
ifconfig eth0 up / down    ->  ip link set eth0 up / ip link set eth0 down
ifconfig eth0 10.0.0.5/24  ->  ip addr add 10.0.0.5/24 dev eth0
route -n                   ->  ip route
route add default gw X     ->  ip route add default via X
arp -a / arp -n            ->  ip neigh
netstat -tulpn             ->  ss -tulpn
netstat -i                 ->  ip -s link
netstat -rn                ->  ip route
netstat -s                 ->  ss -s (summary) / nstat (counters)

Interface names differ per machine — eth0, ens3, enp1s0 — so take yours from ip -br a first. ip -br a (“brief”) is the closest thing to the old ifconfig overview — one line per interface with its state and addresses. For sockets, ss takes the same -t (TCP), -u (UDP), -l (listening), -p (process) and -n (numeric) flags you already know from netstat, and it is faster because it reads kernel socket state directly instead of walking /proc.

How do I fix ping: command not found?

ping is a separate package again, and a different one from net-tools. Minimal images and containers leave it out.

install ping
# Debian, Ubuntu
sudo apt install -y iputils-ping

# Rocky, Alma, RHEL, Fedora
sudo dnf install -y iputils

# Alpine already has a BusyBox ping; this adds the full iputils one
apk add iputils

One ping handles both IPv4 and IPv6 (ping -6 host for v6), and a normal user can run it without root on current distributions. Alpine’s BusyBox already provides a small ping, so there you only need a package if you want the full-featured version.

How do I get ifconfig or ping inside a Docker container?

A container built FROM debian, FROM alpine or similar has neither ifconfig nor ping. Install what you need in the Dockerfile — anything you add by hand in a running container disappears when it is recreated:

Dockerfile
# Debian or Ubuntu base
RUN apt-get update \
 && apt-get install -y --no-install-recommends iproute2 iputils-ping \
 && rm -rf /var/lib/apt/lists/*

# Alpine base (BusyBox already has ping, ifconfig and a basic ip;
# iproute2 adds the full ip and ss)
RUN apk add --no-cache iproute2 iproute2-ss

Better still, do not add tools to a production image at all. To inspect a container’s networking from the host, enter its network namespace instead:

debug from the host, no image change
# find the container's main PID, then look inside its network namespace
pid=$(docker inspect -f '{{.State.Pid}}' myapp)
sudo nsenter -t "$pid" -n ip -br a
sudo nsenter -t "$pid" -n ss -tulpn

# or attach a throwaway debug container that shares the network namespace
docker run --rm -it --network container:myapp nicolaka/netshoot ip a

How do I see which process listens on a port without netstat?

The question people reach for netstat to answer. ss does it, and it can filter by port itself:

who is on port 80?
sudo ss -tulpn 'sport = :80'
# -t tcp  -u udp  -l listening  -p process (needs root)  -n numeric

If what you are really chasing is a bind that fails because the port is taken, the follow-up is in Address already in use, which covers freeing the port and the TIME_WAIT case after a restart.

How do I find my IP address without ifconfig?

ifconfig used to be where people read off their addresses. With ip you can ask for one family at a time, which is handy when a box has both:

addresses by family
ip -4 addr show scope global     # IPv4
ip -6 addr show scope global     # IPv6

scope global hides the loopback and the fe80:: link-local address, so what remains are the routable addresses. That matters more than it used to, because a server today usually has both families — a VMHeaven VPS in Amsterdam, for example, comes with IPv4 and IPv6 — and ip -6 addr is how you confirm the v6 side is actually up.

Networking tools are only the first thing a minimal image is missing — curl and dig are usually the next two. And when the firewall is what is standing between you and the port, the UFW setup guide and SSH connection refused pick up from there.

Another tool missing, or a directory to add to PATH for good in bash, zsh and fish? See command not found: the three causes and the fix for every tool.

Frequently asked

Is ifconfig deprecated?

In practice, yes. ifconfig comes from net-tools, which is in maintenance mode and no longer installed by default on most distributions. It still works once you install it, but it cannot show everything the kernel does, such as multiple addresses on one interface. The maintained replacement is 'ip' from the iproute2 package, which ships on every current Linux.

What replaces netstat?

The 'ss' command from iproute2. It takes the same flags you know — 'ss -tulpn' is the direct equivalent of 'netstat -tulpn' — and it is faster because it reads kernel socket state directly. For the routing table use 'ip route' (netstat -rn) and for interface counters 'ip -s link' (netstat -i).

Why does ifconfig work as root but not as my user on Debian?

ifconfig installs into /usr/sbin, which is not on a normal user's PATH, and since Debian 10 a plain 'su' no longer resets PATH. So the binary exists but your shell cannot find it. Use 'su -' for a login shell, run it with sudo, or call it by full path: /usr/sbin/ifconfig.

How do I install ping in a Docker container?

Add it in the Dockerfile, not by hand in a running container. On a Debian or Ubuntu base: 'apt-get install -y iputils-ping'; on Alpine, BusyBox already includes ping. If ping is present but returns 'socket: Operation not permitted', the binary lacks the cap_net_raw capability or the container's net.ipv4.ping_group_range does not cover your group.

Related articles

All troubleshooting