Postal code formats are one of the first things an international form gets wrong. A field that accepts a few digits and calls it a day will reject whole countries, silently corrupt others, and pass data that no postal operator would recognise. The rules are not complicated, but they are local, and there is no single pattern that covers the world.
This article walks through the main families of postal code in use, the places that have none, the recurring traps around leading zeros and length, and what to do in a form or a database so the data survives contact with real users.
The four families of postal code
Most postal codes fall into one of four broad shapes. The boundaries are fuzzy — a country can change its scheme, and a code can belong to more than one family — but the families are a useful way to think about validation.
- Pure digits of a fixed length. Many countries use a run of digits, commonly four to six of them. Length is fixed within the country, which makes a simple length check viable.
- Digits with a fixed structure. North American codes split into two parts, and the second part is optional in practice, so the same address may carry a short or a long version.
- Letters mixed with digits. Canada, the United Kingdom, the Netherlands and Ireland are familiar examples. Some of these alternate letters and digits in a fixed rhythm; others group characters into segments with distinct meanings.
- Area code plus delivery point. The United Kingdom and the Netherlands are the classic examples: the leading segment identifies a district or town, the trailing segment narrows down to a street or a small group of addresses.
A fifth category matters just as much: countries and territories with no postal code system at all. Asking for a postal code there is not a validation problem to solve but a question that should never have been asked.
Which countries have no postal codes?
Quite a few, including several places people commonly send mail to. Where there is no postal system, a form that insists on a value forces the user to invent one — and the near-universal invention is a run of zeros or a repeat of a single digit. The result is a database full of placeholder values that look like data and carry no information.
The practical answer in two parts. First, make the field optional in any form that serves more than one country, because optionality is the only rule that is correct everywhere. Second, if a downstream system truly demands a value, generate an obvious placeholder and label it as such in the dataset notes rather than pretending it is a real code. The country pages for the markets you serve are a quick way to see which conventions apply where.
Why leading zeros disappear
A postal code is an identifier, not a number. Identifiers get compared, joined, sorted and copied — never added, never averaged, never compared with a greater-than sign. Yet it is extremely common to find a postal column typed as an integer, and that single choice destroys the leading zeros that many national schemes rely on.
The damage is quiet. A code that starts with zero becomes a shorter code when it passes through a numeric column, a spreadsheet, a JSON number field or a system that strips insignificant digits. Nothing errors. The value simply stops being the code it was, and a later postal lookup fails for reasons that look unrelated to the import that caused them.
The same reasoning applies to separators. Some national formats are conventionally written with a space between segments, and users type them inconsistently. Store the canonical form without the separator, or store the separator consistently, but do the normalisation at the boundary and then stop touching it.
Are postal codes and administrative areas the same thing?
No, and the confusion causes real bugs. A postal code describes a delivery route, not a government boundary. Delivery areas and administrative areas overlap, but they do not coincide: one postal code can cover parts of two towns, and one town can span several codes. Codes get reassigned when routes change, without anyone redrawing a province.
That means you cannot derive a city or a region from a postal code with certainty. You can use a postal code as weak evidence — it usually falls inside a known range for a region, and a mismatch between a region and a postal code is a strong signal that at least one of the two was typed wrong. Treat it as a check worth running, not as an authoritative lookup.
This is also why the prefix-based validation that works well in some countries does not transfer. A prefix rule encodes a delivery geography, and every country’s delivery geography is different. The wider picture is covered in the guide to address validation and normalisation.
Postal codes in real forms
A few habits keep a form honest across countries.
- Make the field optional unless you are certain, for a specific country, that a code exists and is required.
- Change the label and the helper text with the selected country, since the shape of a valid code is not portable.
- Accept both the spaced and unspaced forms of a code on input, and normalise to one of them for storage.
- Do not enforce a fixed length globally. A fixed length is only defensible once the country is known.
- Do not uppercase silently if a scheme is case sensitive in some other system; decide on one canonical case and apply it consistently.
A worked example of the same digit string passing one country’s rule and failing another is in the guide to US address structure, where the five-digit and extended forms are described.
For developers: columns, constraints and country switches
Store a postal code as text, at a generous size, with no numeric coercion anywhere in the path. Somewhere between eight and twelve characters is comfortable for every scheme in general use, and the extra space costs nothing compared with a migration later. Trim surrounding whitespace on input, decide whether to keep internal spaces, and apply that decision at one point in the code rather than in every consumer.
Keep the country code next to the postal code, always. A postal code without its country is ambiguous, and no single set of validation rules applies to it. When the country changes in a user interface, clear or revalidate the postal field rather than leaving a value that was checked against the previous country’s rules.
Finally, be prepared for change. Formats get extended, new codes are introduced, and a scheme that looks fixed today can gain a variant tomorrow. A validation rule should be strict enough to catch obvious typos and loose enough to admit a format you did not anticipate. When a code fails validation, log the value you rejected — never the whole record — so you can tell a bad rule from a bad input.
Next steps
Audit one postal column in your own schema and check whether it is text, whether it tolerates leading zeros, and whether the country code travels with it. Then build a small fixture set that includes a digit-only country, a letter-and-digit country, a segmented code, and a country with no postal system at all, and run it through your form. The address generator produces codes in the local shape of each country it covers, which makes that fixture set quick to assemble. Codes produced for a fixture are synthetic by construction: they exercise the format without pointing at a real delivery area, and none of them should end up on a parcel.