ToDo: the plan is to turn this into something that the Release Notes can point at as the nearest thing we've got to an official guide. What if anything does this page need to say about NetworkManager and systemd-networkd?

Anything that changes the names of your network interfaces may result in the machine suddenly not being reachable over SSH, so if you're editing settings on a remote server, plan your changes carefully and doublecheck your safety nets.

This page deals with the various schemes by which wired and wireless network interfaces are assigned names - that is, the underlying system labels like eth0 or wlx800e1319c734. It has nothing to do with the "connection profile" names used by apps such as NetworkManager, like "Wired connection 1".


Back in the nineties, eth0, eth1, etc were simply assigned by the kernel.

Why it was abandoned

At least in theory, if module probes completed in a different order, eth0 and eth1 might switch places on successive boots. As boot processes became less linear and interfaces became more hotpluggable this became more of a concern.

How to get it back

If you wipe out all other name-assignment mechanisms then you'll be left with this one.

The simple way of disabling the whole udev interface naming mechanism (which you might want to try for one-off testing) is just to boot with the kernel parameter net.ifnames=0, which can be set in an interactive grub session at boot or made persistent by editing /etc/default/grub and running update-grub.

Alternatively, you can override /lib/systemd/network/, with a custom version in /etc/systemd/network/, or similarly override /lib/udev/rules.d/80-net-setup-link.rules, or mask the latter by using a /dev/null symlink instead of a custom version, or... there seem to be lots of ways of doing this, so make sure you haven't done it in more than one way or it'll trip you up in a couple of years when you try to undo it. See the external links below on standard methods for overriding systemd configuration. Oh, and beware of initrd skew.

(It's possible that you might also need to disable any legacy 75-persistent-net.rules file, if you've still got a working one and if udev still honors it even when all the rest of this is turned off; if so, see the instructions below for temporarily disabling that file.)


This scheme, introduced somewhere around Debian 5 "Lenny", used udev to identify interfaces by MAC address and assign a fixed interface number to any interface it recognized (writing the rules to /etc/udev/rules.d/75-persistent-net.rules). This could have annoying side-effects (e.g. if you were replacing a machine's sole NIC, you'd also have to take special care to ensure it took over as network interface number 0) but these were minor and predictable.

Newly installed machines since Debian 9 "Stretch" no longer create a 75-persistent-net.rules file - remaining ones on upgraded systems are still honored for now, but this is not expected to remain true in Debian 11 "Bullseye".

Why this one was abandoned

This still had subtle race conditions, required /etc to be on a writable file system, and had problems with virtualization, so it's no longer supported upstream; the plan (still taken for granted in most of the documentation) was for it not to be supported in Debian 10 "Buster", but in the end it has scraped through into another release cycle.

How to cling to it for now

If you've got a working "legacy" /etc/udev/rules.d/75-persistent-net.rules file and want to stick with it, you can safely upgrade through Debian 9 "Stretch" and Debian 10 "Buster"; udev on these releases still respects that file if present. However, bear in mind that eventually this legacy support will end, so you should be ready to switch to a different scheme before that happens.

How to let go and move on

If you've currently got a legacy 75-persistent-net.rules file but have decided to switch to the new regime, you can do that just by disabling the .rules file (then updating the initrd before you reboot); see the udev README.Debian.gz and the more detailed guide below.


(Contributions welcome)

Several workarounds for renaming interfaces grew up in the early days of hotpluggable wireless interfaces, but if they still work it'll be because like ifrename they now use udev rules under the hood. It's not clear what remaining advantage this has over the canonical .link approach - is it perhaps useful for non-systemd machines?

Old releases of RedHat (among others) used a "biosdevname" system, but that's never been supported under Debian. If you need to know about it there's bound to be documentation somewhere.


The new "net.ifnames" approach uses names usually derived from the location of the interface in terms of hardware buses etc: eno1, wlp1s3...

(This system is often advertised as providing "Predictable Names", but the main thing that's predictable about it is that calling it this will cause furious users to pop up disputing the appropriateness of that name. Can we just skip all that here, please?)

How to cope with it on fresh installs

This should be easy enough; before you start configuring firewalls etc., just look at (e.g.) the output of ip a and note the names of the interfaces.

Unlike the old days, when the only way to guess which cable was plugged into eth0 and which was eth1 was to keep track of MAC addresses, this system provides extra clues in the interface names.

How to switch to this scheme on upgraded systems

It's advisable to do this as a separate thing in its own right, not as part of a general distribution upgrade. However, if your PC only has one network interface and not much is at stake you can try:

strategy A

You should probably at least check in advance to see what files hard-code interface names, by running something like

        sudo rgrep wlan0 /etc

(Obvious possibilities include /etc/network/interfaces and configuration files for firewalls, wifi, DHCP...)

strategy B

This strategy, more or less compulsory for remote servers, runs along the lines of:

To find out what names udev would be choosing between if you switched over to the new system, first get a list of the network devices the system knows about:

        echo /sys/class/net/*

For each device path (other than /sys/class/net/lo), ask udevadm what NET_IDs it knows:

        udevadm test-builtin net_id /sys/class/net/enp0s1 2>/dev/null

It's likely to tell you about things like ID_OUI_FROM_DATABASE and an ID_NET_NAMING_SCHEME, but the lines that matter are the ones (given in random order) starting with ID_NET_NAME_. One of these is the name that udev will give priority to - the list of candidates may be so short that all you need to know is that ..._PATH beats ..._MAC, but there are also some rarer possibilities, and in general if something unusual shows up then it will take priority.

From highest priority to lowest, the list is:

  1. ID_NET_NAME_FROM_DATABASE= Very rare and not to be confused with ID_OUI_FROM_DATABASE; if present, it outranks any other ID_NET_NAME. The database is hardcoded into udev and has only one known entry, the spooky-sounding idrac.

  2. ID_NET_NAME_ONBOARD= Appears for some but not all kinds of onboard network card (Ethernet only, or wireless too?) - it's usually a nice simple name like eno0.

  3. ID_NET_NAME_SLOT= Appears for some PCI-hotplug cards. Usually looks like ens0 (again, any wifi cases? Does it ever occur along with _ONBOARD?)

  4. ID_NET_NAME_PATH= Always present; usually something just complicated enough to be easy to forget, like wlp3s5 or enp1s3f0. Note that all numbers are in hex.

  5. ID_NET_NAME_MAC= Also always present, but with a low enough priority that by default it won't be used; e.g. wlx800e1319c734

Complications and corner cases

(Additions welcome, but please try to avoid ballooning this section with tales of "I don't know how this happened but it all went wrong for me"...)


on Debian 9 "Stretch" or newer, merely booting without a net.ifnames=0 override (and without a 70-persistent-net.rules file) should be enough to let you to run the new scheme, but on Debian 8 "Jessie" or older you'll need to actively set it to net.ifnames=1.


the brave way of finding out what network interface names you'll get without a /etc/udev/rules.d/70-persistent-net.rules file is to delete it (and update your initrd before you reboot), but you don't need to go that far. Just renaming it (e.g. to 70-persistent-net.rules.old) or commenting out particular lines should be enough. See the udev README.Debian.gz file. Note that it is possible to have a mixed system with (say) an enp1s1 named from its hardware path alongside a wlan0 still defined as a "persistent" name.


if you're ignoring ID_NET_NAME_SOMETHING on the assumption that anything you don't understand probably isn't important, you need to reread the above - the general rule is, if you don't recognise it, it'll mess things up.


wired devices get a prefixed en- for Ethernet, wireless ones get wl- (and there are also a few more obscure possibilities such as ib- for InfiniBand); then in principle it's possible to decipher all the following sequences of code letters plus hex digits that encode hardware topology. But there's not much point trying to learn all the details, since the only workable way of predicting what ID_NET_NAME_PATH an interface will get is to ask udevadm, which will tell you the whole string.


if you look at /lib/systemd/network/ (at least on Debian 10 "buster") the standard hierarchy of priorities is "keep kernel database onboard slot path" (note that mac only gets considered via a different mechanism). Those first three are poorly documented; the docs confirm that they're real, but the definitions they give aren't much help. It would make sense if keep meant "if something like ifrename gets there first then udev won't re-rename the interface" and kernel meant "if the kernel says there's a net.ifnames=0 override, udev will do nothing".


since they might get plugged into a different socket each time, these use ID_NET_NAME_MAC - automated via /lib/udev/rules.d/73-usb-net-by-mac.rules.


on virtual machines (according to the udev README) you will need to remove the files /etc/systemd/network/ and (if using virtio network devices) /etc/systemd/network/, then rebuild the initrd.


it's all very well having everything sorted out in /etc, but interface renaming has to happen very early during boot; to make sure your initrd doesn't contain out-of-date versions of important systemd files, regenerate it with sudo update-initramfs -u


the old persistent-names system first started being publicly deprecated in NEWS files back in mid-2015, so this upgrade has been hanging ominously over people's heads for a long time. Are you sure you didn't do something about it the last time the subject came up, like setting up a net.ifnames=0 kernel parameter, and/or masking some systemd config file? If so, this may result in confusing symptoms when you try to go over to the new system. Check your administrative logbooks. What do you mean, you don't keep logs?

it turns out even after all this there are still reported cases of interfaces changing their name on a reboot. All that needs to happen is that some buggy BIOS (or some new, less buggy version of a driver module, or systemd's naming policy) changes its mind about some detail like whether or not your hardware counts as the kind that should have an ONBOARD name.


The above is the new standard default scheme, but there's also a canonical way of overriding the default: you can use .link files to set up naming policies to suit your needs. Thus for instance if you have two PCs each of which has only a single wireless card, but one calls it wlp0s1 and the other wlp1s0, you can arrange for them both to use the name wifi0 to simplify sharing firewall configurations. For details see

It's also possible to reorganize the naming policy by overriding the NamePolicy defined in /lib/systemd/network/ (for instance to insist that all network cards are named by MAC address).


Stretch and Buster Release Notes

The nearest thing to a canonical upstream migration-HOWTO used to be The big problem with this was that it delegated all its technical details to a link pointing at the sourcecode: ...but most of the useful comments that used to be at the top of that file were then thrown out, so you need to find your way back through the git tree to a previous version such as Meanwhile, the page now claims to be obsolete, and points instead to (which has much less useful information). So the nearest thing to an official HOWTO is probably /usr/share/doc/udev/README.Debian.gz (though it doesn't cover the "how to predict the names" part at all).

A guide that mentions ID_NET_NAME_FROM_DATABASE:

General guides to overriding systemd configuration:,

CategoryNetwork, CategorySystemAdministration

keywords persistent, predictable, NIC, wlan, eth