The 30-second version
Xero's CSV statement import emits about a dozen error variants — most are misleading. "File is empty" usually means a delimiter mismatch. "Unrecognised date format" usually means an ambiguous DD/MM row that Xero parsed before it gave up. No error at all is the worst case: the file imported, the row count looks right, and every Money-Out figure landed as a deposit. This post decodes every Xero CSV error message — plus the four silent failures that ship wrong numbers without any warning at all.
Xero is polite about CSV import errors in a way that costs you time. Where QuickBooks Online tends to reject a file outright with a curt "Invalid file", Xero will often accept the upload, present a confident column-mapping screen, and only then — after you've clicked Save — produce a vague banner saying something like "We couldn't import this file. Please check the format." Helpful. The format is what you came here to check.
This is the decoder ring. Every Xero CSV error message we've seen in the wild, what it actually means, and the deterministic fix. Then the part nobody warns you about: the four silent failures where Xero swallows the file, the dashboard says X transactions imported, and the numbers are quietly wrong. If you want to skip the rest of this and just get a clean import, our PDF → Xero CSV converter emits a file that passes every check below by construction.
The Xero CSV schema, restated for clarity
Before any error makes sense, you need the schema in front of you. Xero accepts a CSV with these columns, in any order, with these names (case-insensitive but spelling matters):
- Date (required) — the transaction date, not the posting date if they differ. UK and Irish banks sometimes give you both.
- Amount (required) — a single signed number. Negative for money out, positive for money in. No currency symbol, no thousands separator, no Dr/Cr suffix, no parentheses for negatives.
- Payee(optional) — the counterparty. Drives Xero's Bank Rules and contact-suggestion engine, so worth populating cleanly.
- Description (optional) — narrative. Free-form.
- Reference (optional) — invoice number, chq number, FPS reference.
- Cheque Number (optional) — yes, still a column in 2026.
- Analysis Code (optional) — for tracking categories.
The total file size cap is roughly 1MB, and the practical row cap is about 1,000 lines per file before the import gets sluggish. UTF-8, comma-delimited, with a single header row and no preamble. That's the spec. Now the errors.
"The file is empty or invalid"
Xero says this when the parser couldn't identify a single transaction row. It does not mean the file is genuinely empty — it usually means one of:
- Wrong delimiter. Continental Europe defaults to semicolon (
;) as CSV separator. Open the file in a text editor — if the rows look like2026-03-15;Stripe;125,00, Xero parsed the whole row as one giant Date cell and gave up. Fix: re-save as UTF-8 CSV with comma delimiter. - BOM-prefixed file with a non-standard header.Excel on Windows sometimes prepends a byte-order mark to UTF-8 CSVs. Most parsers strip it; Xero historically didn't. Symptom: the first header literally becomes
Date— an invisible zero-width character glued onto the column name — and Xero can't find a Date column. Re-save as UTF-8 without BOM (Notepad++, VS Code, or a script). - The file is a PDF with a
.csvextension. Online banking export buttons mislabel constantly. Open it in a text editor — if you see%PDF-1.7, that's your problem. - Header preamble. Banks love prepending three rows of marketing (Account Statement, Period: 01/03–31/03, blank row) before the actual column titles. Xero reads the first row as the header — gets garbage — decides there are no transactions. Strip those preamble rows.
The 60-second diagnostic
Before re-uploading anything, open the CSV in a text editor (not Excel — Excel will silently re-write it on save). The first line should look like Date,Amount,Payee,Description or similar. The second line should look like 2026-03-15,-125.00,Stripe Inc,Subscription fees. If either isn't true, you've already found the cause.
"Unrecognised date format on row N"
Xero accepts a handful of date formats but is strict about consistency within a file. The accepted formats are YYYY-MM-DD, DD/MM/YYYY, DD-MM-YYYY, MM/DD/YYYY, and the longhand variants like 15 Mar 2026. The trap is that Xero auto-detects the format from the first few rows and then applies that interpretation to the whole file.
If row 1 is 03/04/2026 and Xero guessed DD/MM, the row imports as 3 April. If row 87 is 13/04/2026(unambiguous DD/MM because 13 > 12), Xero accepts it. But if your source file is genuinely mixed — because you concatenated two statements with different locales, or because your bank wrote some rows MM/DD and others DD/MM — Xero throws "unrecognised date format" on the first row that contradicts the guess.
Fix: convert every Date cell to ISO (2026-04-03) before upload. ISO is unambiguous, locale-immune, and survives every re-save. Our converter emits ISO by default precisely because of this.
"We couldn't match the columns"
This appears on the column-mapping screen, after upload but before save. Xero accepted the file structure but can't auto-map your columns to its schema. Three usual causes:
- Money In / Money Out as two separate columns — the UK, Irish, Australian, and New Zealand bank convention. Xero expects a single signed
Amountcolumn. You can either manually map Money Out to Amount and tick the "treat as negative" box on the mapper, then re-upload with Money In mapped the same way — or pre-merge into a single signed column before upload, which is much less error-prone. See our AIB/Lloyds/Barclays → Xero guide for the per-bank specifics. - Localised column headers. A Spanish bank exports
Fecha,Concepto,Importe. Xero can't guess the language and won't auto-map. Translate the header row to English before upload. - Merged-cell headers from Excel.If you opened the bank's CSV in Excel, applied formatting, and exported again, Excel sometimes emits a two-line header where the first line is a section title and the second is the column names. Xero reads only the first. Re-export with a single header row.
Don't fight the column mapper
The column-mapping UI looks helpful but it's a trap. Every manual mapping is a place where a small mistake (Amount mapped to a Description column that contains some numbers) imports cleanly and corrupts your books silently. Pre-shape the CSV to match the schema and never use the manual mapper.
"Amount must be a number"
Self-explanatory but the causes are subtle:
- Currency symbols embedded in the Amount cell.
£125.00or€1,234.56with the symbol attached parses as not-a-number. Strip them. - Comma decimals. A German export writes
1.234,56for one thousand, two hundred and thirty-four point five-six. Xero in en-GB or en-US mode reads this as 1.234 (with,56as garbage trailing characters) at best, or rejects it entirely. Re-emit with dot decimals. - Dr/Cr suffix. Indian and some Asian banks emit
1,234.56 Cr. Strip the suffix and apply the sign to the number. - Parentheses for negatives.
(125.00)looks fine to a human accountant. Xero parses it as a non-numeric string. Convert to-125.00.
"This file appears to have already been imported"
Xero's duplicate-detection looks at Date + Amount + Description across all previously imported statement lines on the same account. If 60% or more of the rows match an existing batch, Xero blocks the import to prevent doubled books.
This usually means one of three things. Either you genuinely already imported this file — check the Statements tab. Or you're importing a fresh statement that overlaps the previous one (last month's statement plus this month's in a single PDF). Or you're re-importing after a bad first attempt that you didn't fully delete.
For overlapping periods: trim the source CSV to only include dates after the last imported transaction. For re-imports after a bad batch: go to Bank Account → Statements → find the bad statement → Delete. This only works if none of the lines were reconciled.Once reconciled, a Statement Line is locked in — you can't delete the whole statement, only un-reconcile and delete line by line. Painful. Our converter ensures you import correctly the first time.
The four silent failures Xero never warns you about
Now the genuinely dangerous ones — files that import "successfully" with the right row count and wrong numbers. The dashboard says 1,247 transactions imported, you breathe out, and three weeks later your VAT return is off by £400.
1. Sign flip on Money-In/Money-Out merged badly
You merged the bank's two columns into one Amount column but reversed the sign convention. Every debit landed as a credit and vice versa. Your closing balance is completely wrong but Xero has no way to know — it doesn't see the bank's opening or closing balance, only the transactions. The reconciliation tab will look normal until you try to actually reconcile against the bank's statement total.
Detection: pick three large transactions you remember (the rent payment, the £8,000 supplier invoice, a known refund) and check the sign in Xero. If rent is a positive amount, your file is sign-flipped.
2. The decimal-comma read as a thousands separator
Variant of the locale trap, but silent. A German file with 1.234,56amounts that Xero auto-parsed as 1.234 (ignoring the comma) will import every transaction at roughly one-thousandth of its true value. The row count is right. Descriptions are right. Every figure is off by a factor of 1,000.
Detection: sum the Amount column in the source bank PDF and compare to the sum in Xero. If they're off by 1,000×, you've found it. Re-emit the CSV with dot decimals and re-import.
3. The transposed digit
A 7 read as a 1 on a single OCR'd row in a 200-line statement. Or a single missing minus sign. Or one row entirely missing from a multi-page PDF where the page break swallowed a transaction. None of this triggers any error in Xero — the import succeeds, the row count is "right" (you didn't count it manually beforehand), and the wrong number is in your books.
Detection is what auto-reconciliation does: opening balance + sum of every transaction must equal closing balance. If the chain breaks, the converter flags the row before the file ever reaches Xero. Run any converted CSV through our free reconciliation checker if you converted it elsewhere.
4. Multi-currency rows imported at the wrong rate
You have a multi-currency Xero org. Your bank statement is in EUR. You imported into a EUR bank account in Xero — so far so good. But your statement contained three rows that the bank had already converted to GBP for you (the cross-border supplier payments). Xero now has those rows in EUR but the underlying ledger truth was GBP. The bank balance reconciles. The expense accounts don't.
Detection: filter the imported batch for any row where the bank's description contains the words "FX", "converted", "exchange rate", or the from-currency code (GBP, USD, etc). Re-categorise those rows manually or use Xero's currency-revaluation feature.
The Xero CSV import error you get is annoying. The Xero CSV import error you don't get is the one that ships your VAT return wrong.
The error → cause → fix mapping table
Print this and pin it above your desk:
| Xero says | Actual cause | Fix |
|---|---|---|
| File is empty or invalid | Semicolon delimiter, BOM, or PDF mis-labelled | Re-save as UTF-8 CSV (no BOM), comma delimiter |
| Unrecognised date format | Mixed or ambiguous DD/MM vs MM/DD | Convert to YYYY-MM-DD |
| We couldn't match the columns | Money-In/Out split, localised headers, or merged cells | Pre-shape into Date,Amount,Payee,Description |
| Amount must be a number | Currency symbol, comma decimal, Dr/Cr, or parens | Strip everything except the digits, dot, and minus sign |
| This file appears to have already been imported | Overlap with prior statement or bad first attempt | Trim overlapping rows; delete bad batch first |
| (no error) but books don't balance | Sign flip, decimal misread, missing row, or FX trap | Use a reconciled converter |
The shortest path to a clean Xero import
- Convert the PDF on StatementEdge. Output: Xero CSV.
- Check the reconciliation badge is green (opening + Σ = closing).
- Download. The file is already ISO-dated, single-Amount, UTF-8, no BOM, no preamble.
- In Xero: Bank Account → Manage Account → Import a Statement → Browse → Upload. Skip the column mapper — every column will already be auto-detected. Confirm. Done.
That bypasses six of the seven error variants above and all four silent failures. Still stuck? Send us a notewith the file and we'll dig into the specifics.
A note on Xero's edition matrix
Manual CSV statement import is available on every paid Xero edition — Starter, Standard, Premium, Cashbook, and Ledger. The only difference is row caps: Starter accounts have a 20-bank-transaction-per-month cap on the broader plan, but statement importsaren't metered the same way (the cap is on reconciled lines, not the import itself). On Cashbook and Ledger (the accountant-only plans), the UI is slightly different — Import a Statement is under Cash Coding rather than Bank Account — but the schema is identical.
One last gotcha: the Statement vs Statement Lines distinction
When you import a CSV, Xero creates two things: a Statement (the batch record, deletable) and a set of Statement Lines(the individual rows). Statement Lines can be reconciled against expected transactions; once reconciled, they're effectively immutable. If you import a bad batch and even one line gets reconciled before you notice, you can't delete the whole Statement anymore — Xero blocks it. You have to un-reconcile every line first, which sometimes reverses the matching of expected transactions you didn't want to touch.
The practical rule: never start reconciling a freshly imported batch until you've eyeballed the first ten rows and the totals. Two minutes of scrutiny up front saves an hour of un-reconciling later.
Further reading
- Xero bank statement import: CSV format that actually works — the comprehensive schema reference, with Bank Rules, payment-processor playbooks, and the Lock Date / MTD workflow.
- Bank statement converter for Xero — the end-to-end workflow with multi-currency and batch-import patterns.
- AIB, Lloyds, Barclays → Xero (2026) — per-bank specifics for the Money-In/Money-Out trap.
- What "auto-reconciled" actually means — why the silent-failure cases are the ones that matter.
- Reconciliation checker — verify opening + Σ = closing on any CSV before you import it anywhere.
- REST API + MCP server — automate the convert-and-import step entirely.