The scenario
You plug a managed switch into your Fedora machine. The network diagram says traffic for the lab servers needs to live on VLAN 100. You run ip link add link eth0 name eth0.100 type vlan id 100 and the interface appears. You assign an IP address and ping the gateway. It works. You reboot the system. The interface is gone. You are back to square one. Fedora does not keep raw ip commands across reboots. You need NetworkManager to own the configuration.
What is actually happening
VLANs are just tags. The 802.1Q standard adds a four-byte header to Ethernet frames. That header tells downstream switches which logical network the packet belongs to. Your physical cable carries everything. The kernel strips or adds the tag depending on the interface. When you use the ip command, you are talking directly to the kernel. The kernel obeys immediately. The kernel also forgets immediately when the interface resets or the system reboots.
NetworkManager solves the persistence problem. It stores connection profiles in /etc/NetworkManager/system-connections/. Those profiles survive reboots, interface flaps, and kernel updates. NetworkManager reads the profiles and applies them to the kernel. You are not configuring the network directly. You are configuring the manager that talks to the kernel.
Think of NetworkManager like a stage manager. The kernel is the actor. The actor can do anything you ask in the moment, but the actor has no memory between scenes. The stage manager holds the script. The stage manager tells the actor what to do at the start of every scene. Fedora uses NetworkManager as the stage manager by default. Trust the stage manager. Manual ip commands drift, profiles stay.
How to configure it with NetworkManager
NetworkManager requires a parent connection profile before it will attach a VLAN. The parent profile must exist and must be managed by NetworkManager. If you created a custom profile for eth0 that disables IP addressing, NetworkManager will still manage the link state. That is enough.
Here is how to create the parent profile if you do not have one yet.
nmcli connection add type ethernet con-name parent-eth0 ifname eth0
# Creates a base profile for the physical cable. NetworkManager needs this to track the link.
nmcli connection modify parent-eth0 ipv4.method disabled ipv6.method disabled
# Disables IP configuration on the physical interface. VLANs carry the IPs, not the trunk.
nmcli connection up parent-eth0
# Activates the parent link so the kernel brings the cable up.
Now create the VLAN profile. The nmcli connection add type vlan command generates a new profile and links it to the parent.
nmcli connection add type vlan con-name vlan100 ifname eth0.100 dev parent-eth0 id 100
# con-name is the profile name in NetworkManager. ifname is the kernel interface name.
# dev points to the parent profile, not the raw interface. id sets the 802.1Q tag.
nmcli connection modify vlan100 ipv4.method manual ipv4.addresses 192.168.100.5/24
# Assigns a static IP to the VLAN. Replace with your subnet and gateway if needed.
nmcli connection modify vlan100 ipv4.gateway 192.168.100.1
# Sets the default route for traffic leaving this VLAN.
nmcli connection up vlan100
# Tells NetworkManager to apply the profile to the kernel immediately.
NetworkManager writes the configuration to /etc/NetworkManager/system-connections/vlan100.nmconnection. You can edit that file directly, but you must run nmcli connection reload afterward. Editing the file without reloading leaves the runtime state out of sync. The nmcli commands are safer because they validate syntax before writing.
If you need to change the VLAN ID later, modify the profile and reactivate it.
nmcli connection modify vlan100 802-1q.vlan-id 200
# Updates the tag in the persistent profile. The runtime interface still shows 100 until you reactivate.
nmcli connection down vlan100 && nmcli connection up vlan100
# Tears down the old kernel interface and rebuilds it with the new tag.
Run nmcli connection reload after any manual file edits. NetworkManager caches profiles in memory. Reload forces it to read the disk.
Verify the configuration
Check the kernel interface first. The -d flag shows detailed flags including the VLAN ID.
ip -d link show eth0.100
# Confirms the kernel interface exists and displays the 802.1Q tag in the output.
You should see vlan protocol 802.1Q id 100 in the output. If the ID is missing, the kernel interface exists but NetworkManager failed to apply the tag. Check the next section.
Check the NetworkManager profile state.
nmcli -f NAME,DEVICE,STATE,TYPE connection show
# Lists all profiles, which device they are attached to, and whether they are active.
The vlan100 profile should show eth0.100 as the device and connected as the state. If it shows unmanaged, NetworkManager is ignoring the interface. Verify that managed=true is set in /etc/NetworkManager/NetworkManager.conf.
Test connectivity. Ping the gateway assigned to the VLAN.
ping -c 4 192.168.100.1
# Verifies Layer 3 reachability on the tagged interface.
If the ping succeeds, the VLAN is active. If it fails, check the switch configuration. The switch port must be configured as a trunk or access port matching the VLAN ID. Fedora cannot fix a misconfigured switch.
Run journalctl -xeu NetworkManager before guessing. Read the actual error before guessing.
Common pitfalls and error messages
The most common failure is a missing or unmanaged parent interface. NetworkManager will refuse to activate the VLAN and print this error:
Error: Connection activation failed: No suitable device found for this connection.
This means NetworkManager cannot find a managed parent profile matching the dev field you specified. Run nmcli connection show and verify the parent profile exists and is in the connected state. If the parent shows unmanaged, run nmcli device set eth0 managed yes and reactivate the parent.
Another frequent issue is conflicting profiles. If you have two profiles trying to claim eth0.100, NetworkManager picks one at random. The other stays deactivated. Delete the duplicate.
nmcli connection delete vlan100-old
# Removes the stale profile. NetworkManager cannot activate two profiles on the same ifname.
VLAN IDs must fall between 1 and 4094. ID 0 and ID 4095 are reserved for priority tagging and protocol identification. If you try to create ID 0, NetworkManager will reject it with Error: Invalid value for 802-1q.vlan-id. Stick to the standard range.
SELinux rarely blocks VLAN creation, but it will block NetworkManager from writing to /etc/NetworkManager/system-connections/ if you changed directory permissions. Restore the default context if you see permission denied errors in the journal.
restorecon -Rv /etc/NetworkManager/system-connections/
# Resets SELinux labels to the Fedora defaults. NetworkManager needs write access to this directory.
Reboot before you debug. Half the time the symptom is gone.
When to use this approach
Use nmcli when you need persistent VLAN configuration that survives reboots and interface resets. Use nmtui when you prefer a terminal-based menu and are configuring a single desktop machine. Use ip link add when you are debugging a live kernel issue or testing a temporary bridge that should vanish after a reboot. Use systemd-networkd when you are building a minimal server image that explicitly drops NetworkManager and you want declarative .network and .netdev files. Stay on the default NetworkManager stack if you only deviate from the defaults occasionally.