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.
Typing a base64 private key into a phone keyboard is unpleasant enough that people copy configs through chat apps instead, which is worse. The QR code exists to avoid both.
It is one command, and the part worth reading is what happens after you scan it.
Generating one
Install the encoder:
apt install qrencode # Debian, Ubuntu
dnf install qrencode # Fedora, RHEL
Then, on the machine holding the client config:
qrencode -t ansiutf8 < /etc/wireguard/client1.conf
The code appears in the terminal, drawn in block characters. Open WireGuard on the phone, add a tunnel, scan from QR code, point the camera at the screen. The tunnel is added with its name, addresses, keys and peer, complete.
There is no special format. The QR code contains the config file as plain text. Anything that can read a QR code can read your config.
For a file instead of a terminal drawing:
qrencode -o client1.png < /etc/wireguard/client1.conf
If the code will not scan, the usual causes are a terminal font that distorts the blocks, or a very long config. -t utf8 instead of ansiutf8 renders smaller, and reducing the terminal font size helps more than anything else.

The part that matters
A WireGuard client config contains PrivateKey. The QR code contains the config. Therefore the QR code is the private key, in a format designed to be read at a distance by a camera.
That changes how it should be handled:
- Do not photograph it. A photo goes into your camera roll and, on most phones, straight into a cloud backup.
- Do not put it in a chat message or an email. Both are stored copies you do not control.
- Clear the terminal after scanning.
clearalone does not empty the scrollback. Usereset, or close the terminal window entirely. - Delete PNG files immediately. A
client1.pngsitting in a home directory outlives the reason it was created. - Do not display it where a camera can see it, which in a shared office includes the window behind you.
One private key per client is the rule the QR code makes easy to break. Generating one config and scanning it onto three phones gives all three the same identity, and the server then cannot tell them apart, cannot revoke one, and will misroute traffic when two are connected at once. Adding a distinct peer per device is covered in adding a WireGuard peer.
Generating the config first, if you do not have one
The QR code is the last step. Before it, the client needs a key pair and a peer entry on the server:
wg genkey | tee client1.key | wg pubkey > client1.pub
Then a config referencing the server's public key, endpoint and AllowedIPs, and a matching [Peer] block on the server carrying client1.pub. Skipping the server side is the most common reason a scanned tunnel connects to nothing: the phone is configured, and the server has never heard of it.
Full walkthroughs, including the server side, are in PiVPN WireGuard setup for a Raspberry Pi and self-hosting on a VPS for a rented server. Both generate client configs you can pipe straight into qrencode.
If the scan works but the tunnel does not
The QR code has done its job the moment the tunnel appears in the app. Everything after that is ordinary WireGuard.
Check the phone shows a recent handshake. If it does not, work through handshake troubleshooting: endpoint address, port reachable from outside, server firewall, and the peer entry. If the handshake succeeds but pages hang, that is MTU, and it is especially common on mobile networks.
Platform specific setup notes are in WireGuard Android setup and WireGuard iOS setup.
★ 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→


