Sample dataset · CC0

A file that is wrong in nine specific ways.

Every other dataset here is clean. This one is not, and each of its defects is a real thing that happens to real files: ragged rows, a repeated header name, four date formats in one column, mojibake, zero-padded ids, European decimals, blank rows, a stray carriage return and padded cells.

6 columns · 100 or 1,000 rows as a file · up to 1,000,000 rows generated here · CSV

Take the file

CSV only, and the reason is worth stating: most of these defects cannot exist in a typed format. You cannot have a ragged row in Parquet or four date formats in one Excel column, so shipping this as anything but text would quietly fix the file and defeat the point.

Format Small Standard
CSV100 rows (7.0 KB)1,000 rows (69.6 KB)

A bigger broken file

The defects repeat on a fixed cycle, so a hundred thousand rows carries about eight thousand blank rows and six thousand ragged ones. That is a far heavier defect rate than a real file, which makes it a stress test rather than a simulation.

The first eight rows, split naively

The first eight rows of the 100-row file, split naively on commas so you can see the damage. Row four onward is where it starts getting interesting.

invoice_nocustomerdateamountcurrencynotesnotes
0000001Ana Novák2026-03-14"2.63712"USDpaid in full
0000002Jörg Müller03/14/2026"1978.51"USD"customer said ""send it twice"""
0000003Zoë Fitzgerald14.03.2026"3738.32" USD "follow up
0000004Renée Dubois14 March 2026"6.95590"USD"split shipment
second box pending"extra-field
0000005Søren Kierkegaard2026-03-14"1476.95"USD padded on both sides
0000006Chloé Martin03/14/2026"4885.30"USD
0000007Ana Novák14.03.2026"4.39351"USDpaid in full

What the columns are supposed to be

Column Type What it holds Example
invoice_no text Zero padded invoice number. Every value loses its leading zeros the moment Excel opens the file. 0000001
customer text Customer name. Some rows carry mojibake where a UTF-8 name was read as Latin-1. Ana Novák
date text Four different date formats in one column: ISO, US, EU and a written month. 2026-03-14
amount text Mixed decimal conventions. Some rows use 1.234,56 and some use 1,234.56. "2.637
currency text Currency code, sometimes padded with spaces. 12"
notes text Free text with unescaped quotes and an embedded newline. The second column named notes is a duplicate header. USD

The nine defects, one at a time

The header names a column twice. It reads invoice_no, customer, date, amount, currency, notes, notes, which is seven fields for six documented columns. Most parsers silently keep the last one, some silently keep the first, and a few rename the second to notes_1. All three behaviors are defensible and they are not the same, which is why you want to know which one yours does.

Rows are ragged in both directions. Every seventeenth row is short by one field and another is long by one, so a parser that pads, a parser that truncates and a parser that errors all give different results. Ragged rows are the single most common defect in files exported from bespoke internal systems.

Dates arrive in four formats in one column: 2026-03-14, 03/14/2026, 14.03.2026 and 14 March 2026. That is one column that no single format string will parse, and the middle two are genuinely ambiguous with each other on any day of the month up to twelve.

Amounts mix conventions. A third of the rows are written 2.637,12 and the rest 1,978.51, both quoted. Read the first with an English parser and you get 2.63712 or a failure, and read the second with a German one and you get the same problem in reverse.

And the other five

Invoice numbers are zero padded to seven digits with no prefix, so 0000001 is a bare numeric string. This is the harsh version of the leading-zero problem: open the file in almost any spreadsheet and the column becomes 1, 2, 3 with no warning and no undo.

Every ninth row carries mojibake. Jörg Müller appears as Jörg Müller, which is the exact byte sequence you get when UTF-8 is read as Latin-1. Alongside it are correctly encoded rows with the same names, so the file lets you see both states of the same string next to each other.

Every twelfth row is completely blank, which is what you get from a spreadsheet that was saved with empty rows between records. Every twenty-third row ends with a carriage return before the newline, so the file mixes CRLF and LF line endings and a tool that assumes one will produce trailing invisible characters on those rows.

One in five currency cells is padded to " USD " with a leading and trailing space, which is invisible in a viewer and fatal to an equality comparison. The notes column carries unescaped-looking text with doubled quotation marks and one embedded newline, so a row spans two physical lines and a line-based reader breaks on it.

How to use it

Run it through the CSV validator first. It should report the structural problems with line numbers, which gives you a baseline of what a careful reader sees. Then open the same file in whatever you are evaluating and compare: the differences between the two reports are the defects your tool is silently absorbing.

The other use is regression testing. Because the file is deterministic, the row where each defect appears is fixed, so you can write an assertion about row 12 being blank or row 9 carrying mojibake and it will keep passing. Most broken-file test fixtures are somebody's one-off export, and they rot.

It is worth being clear about what this file is not. The defect rate is far higher than any real file, roughly one row in twelve blank and one in seventeen ragged, because the point is to exercise every path quickly rather than to simulate a plausible export. Treat it as a stress test.

What people use it for

  • Testing a CSV parser against ragged rows, duplicate headers and mixed line endings.
  • Proving that a date parser cannot handle four formats with one format string.
  • Showing what a spreadsheet does to a zero-padded numeric identifier.
  • Encoding work: mojibake and correctly encoded versions of the same names, side by side.
  • Regression tests with fixed defect positions that do not rot.

License, and the people in it

This dataset is dedicated to the public domain under CC0 1.0. Put it in a course, a paid product, a test suite, a bug report, a screenshot, a conference talk or a book. There is nothing to ask for, nothing to sign and no attribution required. A link back is welcome and is not a condition.

The names in this file are real-looking European names with diacritics, chosen because diacritics are what mojibake destroys. They are drawn from a fixed pool and belong to nobody, and there are no addresses, contact details or identifiers anywhere in the file.

Questions people ask about this file

Why is this CSV only?

Because most of the defects cannot survive a typed container. Parquet has a schema, so a ragged row is not expressible. Excel has one type per cell, so four date formats in a column collapse. Shipping this file as anything but plain text would quietly repair it during the conversion and hand you a clean file with a misleading name.

What exactly is wrong with it?

Nine things. A duplicate header name, ragged rows both short and long, four date formats in one column, mixed decimal conventions, zero-padded numeric ids, mojibake on every ninth row, blank rows, a stray carriage return giving mixed line endings, and cells padded with spaces. The notes column also carries doubled quotation marks and one embedded newline.

Are the defects always in the same rows?

Yes, and that is what makes the file useful in a test suite. The pattern is fixed: every twelfth row is blank, every seventeenth is ragged, every ninth carries mojibake, every twenty-third ends in a carriage return. Write an assertion about a specific row and it will keep passing, which is more than can be said for a broken file somebody found once and checked in.

Is the defect rate realistic?

No, it is much worse than a real file, deliberately. Roughly one row in twelve is blank and one in seventeen is ragged, which no real export would survive. The goal is to exercise every failure path within the first hundred rows rather than to simulate a plausible file, so treat the results as a stress test rather than as a prediction.

Where do I find the clean version of this data?

There is no clean twin of this exact file, because the schema exists only to carry the defects. If you want realistic invoice-shaped data that is well formed, use the expenses dataset, which has claim ids, amounts, currencies and merchants and is correct throughout. The comparison between the two is instructive on its own.