VPNSmith
self-host-vpnINFO

wg-quick: Bad address. The Line Is Almost Always Missing Its Prefix

One error, and four ways to produce it: a missing CIDR suffix, a host address written where a network was meant, an IPv6 form the tool will not take, or an Endpoint that no longer resolves. How to tell which one you have before changing anything.

By Eric Gerard · Founder · VPNSmith - Self-host VPN & GDPR VPS specialist4 min readPhoto via Pexels

Affiliate disclosure - This post contains Contabo affiliate links. If you grab a VPS through them, we earn a commission at no extra cost to you.

wg-quick: `10.10.0.2' is not a valid address

or, depending on the version and the field:

Bad address

Two fields in a WireGuard config carry addresses, and both must carry a prefix length. Address in the [Interface] block, and AllowedIPs in each [Peer] block. Almost every occurrence of this error is a missing /32 or /24.

Why the prefix is not optional

WireGuard configures a network interface, and an interface needs to know the size of the network it sits on, not just its own address. 10.10.0.2 alone does not say whether 10.10.0.7 is on the same network or somewhere else, and the kernel has to know before it can build a routing table.

So:

[Interface]
Address = 10.10.0.2/32      # correct
Address = 10.10.0.2         # Bad address

The same applies to AllowedIPs, which is a list of networks and never a list of bare hosts.

/32 or /24 on a client, and it is not a style choice

Both parse, and they do different things.

/32 says: this address is mine, and nothing else is directly on this interface. Every other destination is reached through a route, which is what AllowedIPs on the peer describes. This is what you want on a client in almost every setup.

/24 says: the whole 10.10.0.0/24 range is directly reachable on this interface. The kernel adds a route for the entire subnet. On a hub and spoke layout where other clients are reached through the server, that route competes with the one you actually need, and the symptom is other peers becoming unreachable while the server still works.

On the server, /24 is usually correct, because the server genuinely is the network for its peers.

Two arched orange doorways side by side in an orange rendered wall, each with plain doors and small white number plates reading 82, 84 and 86
Two arched orange doorways side by side in an orange rendered wall, each with plain doors and small white number plates reading 82, 84 and 86

IPv6, where the form is stricter than people expect

Address = 10.10.0.2/32, fd86:ea04:1115::2/128

Two things go wrong here. The abbreviated form must be valid: fd86:ea04:1115::2 is fine, fd86:ea04:1115:::2 with three colons is not, and the difference is easy to miss when reading. And the prefix is required on the IPv6 entry too, /128 for a single host.

If the machine has IPv6 disabled at kernel level, adding an IPv6 address fails at a later stage with a different message. Worth knowing so you do not chase the wrong error.

The cause that survives every rewrite

A config copied through a chat application, a ticket system or a word processor can carry characters that are invisible on screen:

  • a non-breaking space instead of a space around the =
  • an en dash instead of the hyphen in a range
  • a zero width character before the address
  • Windows line endings, which some parsers tolerate and others do not

The file looks right. The parser disagrees. One command settles it:

cat -A /etc/wireguard/wg0.conf | head -20

Real spaces appear as spaces, line ends as $, and anything unusual shows up as an escape sequence. If you have rewritten the line three times and it still fails, this is why, and retyping the line by hand rather than pasting it is the fix.

Checking the whole file before bringing the interface up

wg-quick strip wg0

This prints the config as WireGuard will read it, with the wg-quick specific lines removed, and it fails on a malformed value without touching your network. It is the safest way to test a config on a remote machine, because a broken wg-quick up on your only route in is a long walk to the console.

When it is not the address at all

If Address and AllowedIPs both carry prefixes and the error persists, check Endpoint. A hostname that no longer resolves produces a failure at almost the same moment, and the two are easy to confuse. dig +short vpn.example.com answers that in a second.

Once the interface comes up, the next problems are different ones: no handshake at all is handshake troubleshooting, a handshake with stalled traffic is MTU, and traffic reaching the wrong place is AllowedIPs, which is the same field as here but a different mistake.

★ Nuremberg GDPR datacenter · ✓ Dedicated IPv4 included · 200+ Mbps guaranteed

Self-host your VPN on your own VPS → ContaboFull root access · public IPv4 · pick your region

Frequently asked questions

What does Bad address mean in wg-quick?
It means a value that should be an IP address or a network was rejected by the tool parsing it. The two fields that produce it are Address in the Interface section and AllowedIPs in a Peer section, and in the large majority of cases the value is missing its prefix length.
Does the Address line need a subnet mask?
Yes. WireGuard configures a network interface, so it needs to know the size of the network on that interface, not only the address. Address = 10.10.0.2 is rejected; Address = 10.10.0.2/32 is accepted.
Should I use /24 or /32 on the client Address?
Use /32 unless you deliberately want the client to consider the whole subnet directly reachable on the tunnel interface. A /24 on a client adds a route for the entire range, which conflicts with peers you reach through the server rather than directly.
Why do I get Bad address on a working config after moving it?
Copy through a chat client or a word processor is the usual cause: a non-breaking space, a smart dash in place of a hyphen, or an invisible character before the address. The file looks correct on screen and the parser disagrees. cat -A shows what is really there.
Can an Endpoint cause this error?
An Endpoint that fails to resolve gives a different message, usually about name resolution, but people report both together because a hostname that resolves to nothing and an address that will not parse fail at roughly the same moment in the process.