You have seen one taped to the wall of a café or printed on a hotel key card. Someone opens the camera, a prompt offers to join the network, and that is the end of it. No spelling out a 20-character passphrase over the noise of an espresso machine.
It looks like the code fetched something. It did not. A Wi-Fi QR code is a picture of a short piece of text, and the text is your network name and your password, sitting there in the clear. That one fact explains both why the codes work so well and why the ones that fail, fail in a way nobody can debug.
Here is what the format contains, the escaping rule that quietly breaks codes, and what to check before you print one. Our Wi-Fi QR code generator applies every rule below, in your browser.
What is in the square#
Most QR codes you meet hold a URL: scan one and the phone opens a browser. A Wi-Fi code holds a string beginning WIFI:, which phones recognise as network credentials rather than as a web address.
A minimal one looks like this:
WIFI:T:WPA;S:CafeGuest;P:flatwhite2026;;
That is the whole payload. No server, no lookup, no short-lived token issued to the person scanning. The camera decodes the text, recognises the prefix, splits the fields apart and hands them to the operating system, which offers to join. The picture is the credential.
One consequence follows immediately: any QR scanner pointed at that code can show you flatwhite2026 as text, and plenty of scanner apps display the decoded string before acting on it.
The format, field by field#
The fields are separated by semicolons, each introduced by a single-letter key.
T:the authentication type. The values in the original format description areWEP,WPA,WPA2-EAPandnopass. In practiceWPAis what generators emit for anything using a shared passphrase, WPA2 and WPA3 included, which is why our generator labels that option WPA / WPA2 / WPA3. The field describes the style of credential rather than the exact handshake the router negotiates.S:the SSID, meaning the network name. Required.P:the password. Ignored when the type isnopass, and better omitted entirely there, because some clients prompt for a password anyway when they see an empty field.H:the hidden flag, set totruefor a network that does not broadcast its name. Leave it out otherwise, since some older scanners mishandle an explicitH:false.
The record ends with two semicolons: one closing the final field, one terminating the record. A code missing that second semicolon is a common cause of a scan that does nothing.
Worth knowing about the standing of all this: there is no RFC for it. The format began as a convention documented in the ZXing barcode library and became a de facto standard because the phone vendors implemented that convention. IANA's URI scheme registry does carry a wifi entry, but as a provisional registration from the Wi-Fi Alliance rather than a standards-track specification. It is well specified in the sense that everyone agrees, and loosely specified in that no standards body owns the grammar.
Escaping is where codes break#
Semicolons separate fields, so a semicolon inside a value would end that field early. The format solves this with backslash escaping, and five characters need it inside the SSID and the password:
\ ; , : "
Each must be written with a backslash in front. A network named Cafe;Guest has to be encoded as S:Cafe\;Guest. Skip that and the parser reads the SSID as Cafe and treats Guest as a malformed field.
This is the failure worth understanding, because of how it presents. The code still scans. The phone still shows a join prompt. It then joins the wrong name, or attempts the right name with a truncated password and reports only that it could not connect. Nothing on screen looks wrong, there is no error text to search for, and the person is looking at a picture of a square. Colons turn up in generated passwords constantly, which makes them a common trigger.
This is a small argument for keeping a guest passphrase to letters and digits, and a much better one for using a generator that escapes properly, so the character set stays your choice.
The all-hex SSID trap#
There is a second ambiguity, rarer but confusing when it lands. An SSID made only of hexadecimal digits can be read by some clients as a raw hex value rather than as the text you typed. ABCDEF1234 is a legitimate network name and also a legitimate sequence of hex bytes.
The format's answer is to wrap such a name in double quotes, which forces a literal reading: S:"ABCDEF1234". The lengths where the ambiguity arises are 10, 26, 32, 58 and 64 hex digits, matching key lengths that clients already expect to see written that way. Our generator detects this and quotes the name for you rather than leaving it to chance.
Lengths the router will accept#
A QR code will happily encode credentials no router would ever accept, so it is worth knowing the limits the radio imposes.
The SSID is capped at 32 octets. Octets, not characters. The 802.11 SSID element carries a raw byte sequence of 0 to 32 bytes, and the standard does not specify a character encoding for it. Under UTF-8 an emoji costs four bytes and a kanji costs three, so a name that looks short on screen can sit over the limit.
A WPA passphrase is 8 to 63 characters. That is the range defined for the pre-shared key passphrase in 802.11, and it holds for WPA2-Personal and WPA3-Personal alike. Seven characters is not a weak password, it is an invalid one, and most devices refuse it outright.
WEP keys come in four lengths, and only four: 5 or 13 ASCII characters, or 10 or 26 hexadecimal digits, corresponding to 64-bit and 128-bit WEP. If you are still choosing WEP, the more useful fact is the date. Fluhrer, Mantin and Shamir published a passive attack recovering the RC4 key from eavesdropped traffic in August 2001, and the IEEE deprecated WEP in 2004 when it ratified 802.11i. Any router still offering it also offers something better.
Our generator checks all of this and reports it as advice rather than refusing to build the code. Length problems produce the harder failure: a code that scans perfectly and then will not connect.
Error correction and the quiet zone#
QR codes carry redundancy so a damaged one still reads. The standard defines four levels, and the difference between them is how much of the code can be lost:
- L recovers roughly 7% of the codewords
- M recovers roughly 15%, and is the level most commonly selected
- Q recovers roughly 25%
- H recovers roughly 30%
Redundancy is not free. A higher level packs more data into the same symbol, so at any printed size the grid is denser and the squares smaller. For a code on a screen the lowest level is fine. For one taped to a wall, scuffed and eventually rained on, the higher levels earn the space.
Then there is the quiet zone, the blank margin around the code. The specification calls for four modules of clear space on all four sides, a module being one of the small squares. Scanners use that margin to find the symbol's edges. A code cropped flush to its border, or dropped onto a busy background image, often will not lock on at all. It is the most common print failure after simply making the thing too small.
Our encoder covers QR versions 1 through 10, from a 21×21 grid up to 57×57, and includes the four-module margin in the file it hands you. That range holds a 32-byte name plus a 63-character passphrase with room to spare, so the printed size is decided by legibility rather than by capacity.
The part nobody prints on the poster#
Anyone who can photograph the code has your Wi-Fi password. Not a guest token, not a time-limited invitation, not something you can revoke. The passphrase itself, in plain text, recoverable from a photo taken across the room and readable months later.
Usually that is exactly what you meant, because a guest network password is meant to be shared. It stops being fine when the code is for the network your file server, printer, cameras and laptops sit on. Joining that network puts a stranger inside the same private address range as every device in the building, which is a different proposition from being handed the internet.
The fix is dull and effective: put visitors on the guest network. Consumer routers have shipped one for well over a decade, and it is the whole difference between giving out your connection and giving out your devices. While you are picking that passphrase, our password breach check will tell you whether it has already turned up in a breach corpus, without ever sending the password itself.
One more property matters, and it is why the tool is built as it is. The credentials you type build the URI and draw the matrix in your own browser; nothing you enter is sent anywhere to produce the code. That is the only sensible arrangement for a page whose input is a live Wi-Fi password.
When the scan does nothing#
Working failures back to a cause, roughly in order of how often each one is the answer:
- The camera sees nothing at all. Size or margin. A code needs about two centimetres square at normal phone distance, more if the passphrase is long, since a longer payload means a denser grid. Check that the quiet zone has not been cropped.
- It scans and offers to join, then fails. Almost always an unescaped character in the password, or a passphrase outside the 8 to 63 range. Decode the code with any generic QR reader and read the raw string; the truncation is obvious once you can see the text.
- It joins a network with the wrong name. An unescaped character in the SSID, cutting it short at the first semicolon, comma or colon.
- The security type does not match. A network running WPA2 or WPA3 that the code declares as
WEPwill not connect. - The network is hidden and the code does not say so. Without
H:truethe phone will not go looking for a network that is not broadcasting.
The technique is the same in every case: decode the code as plain text before blaming the encoder or the phone. The payload is short and human-readable, and tells you in one line which of the five went wrong.
Build a Wi-Fi QR code
Enter the network name and passphrase and get a scannable code, with the escaping and hex-quoting handled for you. It flags SSIDs over 32 bytes and passphrases outside the WPA range before you print, offers all four error-correction levels, and downloads as SVG with the margin intact. Everything is built in your browser.
Generate a code →