WireGuard Cannot Create Its Interface: Kernel or Permission?
Interface creation fails before any peer handshake. Read the error to tell a missing module from a privilege boundary or an existing interface owner.
WireGuard fails to create its interface, so there is no device to configure, no key to exchange and no handshake to debug. The failure sits entirely on the local machine, and the error text says which part of the local stack refused. Reading it correctly is faster than reinstalling the peer's configuration. The layers are separable, and the message names the one that refused.
The error happens before any peer speaks
Creating an interface is one netlink request to the kernel asking for a device of type wireguard. The kernel either has a driver that understands that type or it does not, and the answer comes back immediately. No packets leave the machine during this step, which is why endpoint addresses and server keys cannot be the cause.
That ordering matters for diagnosis. If the command never created a device, the problem cannot be a wrong public key or a blocked UDP port. Fix the local creation path first and only then look outward.
Which implementation is supposed to own the device
Two implementations can answer that request. The in-kernel module registers the wireguard device type, and a userspace implementation such as wireguard-go provides the same interface through a different mechanism. If the module is absent, the kernel rejects the request with an unsupported-device error, and the fix is either to load the module or to point the tools at the userspace implementation.
Check what is actually present before choosing between them. The first command shows whether the module is loaded and the second asks the kernel directly:
lsmod | grep wireguard
ip link add wgtest0 type wireguard
The second command is the smallest possible reproduction: it asks for a device and nothing else. If it fails with an unsupported-type message, the missing piece is the implementation rather than your configuration file.
| Error text | What refused | Next step |
|---|---|---|
| Unknown device type or operation not supported | The kernel has no wireguard driver | Load the module or use the userspace implementation |
| Operation not permitted | Missing privilege | Use the service context or grant the capability |
| File exists | The name is already in use | Inspect the owner before touching it |
| No such device in a container | No tunnel device or capability | Add the device and NET_ADMIN to the container |
Privileges and container boundaries
Creating and configuring a network device requires privilege, either as root or with the network administration capability. A normal user session cannot do it, and that restriction is the design rather than an obstacle to work around by running an installer you have not reviewed.
Inside a container the boundary is doubled. The container needs access to the tunnel device and the capability to configure it, and the flags that grant those are the same ones a Linux VPN container uses. A restricted guest that can browse the web normally still cannot create an interface, because browsing needs no such capability. Grant the capability to the service that needs it rather than to every session on the host.
Resolve the name conflict, then retry
An interface that already exists is not automatically a leftover. Another manager may own the name and be using it right now, so inspect it before deleting anything:
ip link show wg0
sudo wg show wg0
If the owner is an active service, configure that service instead of creating a second device. If it is genuinely stale, remove it through the tool that created it, then bring the interface up with the documented client or unit so the configuration and the device stay in step.
Once creation succeeds, the next failure belongs to a later stage, and a unit that reports failure after the device exists is a different problem from a device that was never created. Separate the two before changing permissions again.