Why Faker's UK Postcodes Fail Validation

Validation · October 2026 · 9 min read

Faker is the default test-data library in JavaScript, and roughly 70% of the UK postcodes it generates are not valid postcodes. Here is the measurement, the single bug behind most of it, and the code to reproduce the numbers yourself.

Faker is the default way to generate test data in JavaScript, and for UK postcodes it is wrong about 70% of the time. That is a measurement, not an opinion. Here is the method, the numbers, and the code to reproduce them.

The measurement

Faker 10.6.0, locale en_GB, faker.location.zipCode(), 50,000 postcodes, checked against two validators:

The looser figure is the floor. Nearly half of Faker's UK postcodes are not even the right shape, before you ask whether the letters it used are permitted ones.

Reproduce it


import { fakerEN_GB as faker } from '@faker-js/faker';

// Royal Mail's permitted letters per position.
const UNIT = 'ABDEFGHJLNPQRSTUWXYZ';      // never C, I, K, M, O, V
const FIRST = 'ABCDEFGHIJKLMNOPRSTUWYZ';  // never Q, V, X
const SECOND = 'ABCDEFGHKLMNOPQRSTUVWXY'; // never I, J, Z
const THIRD = 'ABCDEFGHJKPSTUW';
const FOURTH = 'ABEHMNPRVWXY';

const POSTCODE = new RegExp(
  '^(?:GIR ?0AA|(?:' +
    `[${FIRST}](?:[0-9][0-9]?|[0-9][${THIRD}])` + '|' +
    `[${FIRST}][${SECOND}](?:[0-9][0-9]?|[0-9][${FOURTH}])` +
  `) ?[0-9][${UNIT}]{2})

  
    
    

    
    

    Why Faker's UK Postcodes Fail Validation | UK Random Address Generator
    
    
    

    
    
    
    
    
    
    
    

    
    
    
    
    
    

    
    
    
    
    
    
    
    
    
    
    
    
    
    
  
  
  
  
    
);

let invalid = 0;
for (let i = 0; i < 50000; i += 1) {
  if (!POSTCODE.test(faker.location.zipCode().toUpperCase())) invalid += 1;
}
console.log(`${(invalid / 500).toFixed(1)}% invalid`);

Note the anchoring. Written as ^A|B$ a pattern like this binds as (^A)|(B$), which silently accepts anything ending in a valid postcode — a mistake worth checking for in your own validator, because it inflates your pass rate rather than your failure rate.

Seed Faker and the same postcodes come out every time:


faker.seed(42);
Array.from({ length: 10 }, () => faker.location.zipCode());

Six of the first ten.

Two failure modes, one of them trivial

The inward code has the wrong grammar. A UK inward code is always one digit followed by two letters: 1AA, 7PE, 8TH. Faker emits a digit, a digit and a letter: 67A, 61B, 79X. Every one of the 24,175 format failures is this single bug. The outward code was malformed zero times in 50,000 draws. One wrong character in one pattern accounts for the entire format failure rate.

The letters are not filtered. The remaining 22 percentage points come from letters the postcode system never uses. C, I, K, M, O and V never appear in the unit, because they are too easily confused when read by hand or by machine. SW9 8HC passes a naive [A-Z]{2} check and is not a postcode.

What Faker gets right

Credit where it is due: the postcode area is always real. Across 50,000 draws Faker produced 121 distinct areas and not one invented one — no ZZ, no QQ. It is working from a real list.

The district is where that stops. 4.9% of outputs carry a leading zero — CT08, SL08, YO05 — and no UK postcode district has ever had one. The digits after the area are random, not allocated.

Why a better pattern would not fix it

The pattern could be corrected. The allocation cannot. A postcode is valid in three independent senses, and a format string only ever reaches the first:

1. Shape. Does it match one of the six permitted forms, using permitted letters? A regular expression settles this. 2. Allocation. Is CT08 a district Royal Mail actually issues? This needs the list of real districts. 3. Delivery. Does post arrive there? This needs the Postcode Address File.

Faker is a general-purpose library spanning dozens of locales. Carrying the allocated district list for each of them is not its job. The trouble starts when a pattern is treated as a substitute for one.

What this costs in a test suite

A generator that is 70% invalid does not fail loudly. It fails selectively, which is worse:

  • Your postcode validator's tests pass, because the fixtures that reached them happened to be in the valid 30%.
  • A form test is red on CI and green locally, because the seed differed.
  • Someone "fixes" a correct validator to accept SW9 8HC, shipping a regex that now waves through real rubbish.
  • Address matching or deduplication is tuned against data whose distribution does not resemble the real thing.

The last one is the expensive one. A matcher tuned on structurally impossible input learns the wrong thresholds, and it learns them quietly.

What to do instead

If you only need the shape to be right, keep Faker for names, emails and dates, and generate postcodes from a correct pattern. Then use the validator above as a test-time assertion — a one-line guard that fails the suite the moment a fixture is impossible. That is exactly how the numbers in this article were produced.

If you need real districts, you need an allocated district list, which means maintaining one or calling something that already has one. The random UK postcode generator builds every postcode on a real Royal Mail district with a structurally valid inward code, and the REST API returns them as JSON for use in CI. Full postcodes are deliberately never live delivery points, which is the difference between test data and a postcode lookup.

If you need to confirm that post actually arrives, no generator will do. That is a licensed PAF provider, covered in where UK address data comes from.

Versions and caveats

Measured on @faker-js/faker 10.6.0, locale en_GB, in October 2026. A later release may change this, so rerun the snippet before quoting the figure. The method is the durable part: assert your fixtures against the format rules and find out what your generator is really handing you.

The letter-by-letter rules are set out in the UK postcode format explained, and working implementations for JavaScript, Python and SQL are in validating UK postcodes in code. To check a single postcode by hand, use the address and postcode validator.

More guides