All posts
bank-statement-converterxerocsvaccountingguidehow-totroubleshooting

Xero CSV import errors decoded: every error message and the actual fix

Every Xero CSV statement-import error decoded into actual cause and fix. The six error messages you'll see ("file is empty", "unrecognised date format", "we couldn't match the columns", "amount must be a number", "already imported", and the polite mapping-screen reject), the BOM / delimiter / preamble traps behind each, plus the four silent failures Xero never warns you about — sign-flipped Money-In/Out merges, decimal-comma read as thousands separator, single transposed digits in OCR'd rows, and multi-currency rows that reconcile the bank balance while corrupting the P&L. Includes the schema reference, the column-mapper warning, the Statement vs Statement Lines deletion trap, and a print-this-and-pin-it mapping table.

StatementEdge··9 min read

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 like 2026-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 .csv extension. 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.00 or €1,234.56 with the symbol attached parses as not-a-number. Strip them.
  • Comma decimals. A German export writes 1.234,56 for one thousand, two hundred and thirty-four point five-six. Xero in en-GB or en-US mode reads this as 1.234 (with ,56 as 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 saysActual causeFix
File is empty or invalidSemicolon delimiter, BOM, or PDF mis-labelledRe-save as UTF-8 CSV (no BOM), comma delimiter
Unrecognised date formatMixed or ambiguous DD/MM vs MM/DDConvert to YYYY-MM-DD
We couldn't match the columnsMoney-In/Out split, localised headers, or merged cellsPre-shape into Date,Amount,Payee,Description
Amount must be a numberCurrency symbol, comma decimal, Dr/Cr, or parensStrip everything except the digits, dot, and minus sign
This file appears to have already been importedOverlap with prior statement or bad first attemptTrim overlapping rows; delete bad batch first
(no error) but books don't balanceSign flip, decimal misread, missing row, or FX trapUse a reconciled converter

The shortest path to a clean Xero import

  1. Convert the PDF on StatementEdge. Output: Xero CSV.
  2. Check the reconciliation badge is green (opening + Σ = closing).
  3. Download. The file is already ISO-dated, single-Amount, UTF-8, no BOM, no preamble.
  4. 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

Keep reading

bank-statement-converterxero

Xero bank statement import: CSV format that actually works

The exact CSV schema Xero accepts — two required columns plus five optional, the date format rules (ISO recommended), Amount column quirks (no parens, no currency symbols, no Dr/Cr suffix), header preamble traps, encoding (UTF-8) and delimiter (comma) rules, the seven silent-failure modes that import 'successfully' with wrong numbers, manual-vs-bank-feed decision tree, Bank Rules engine design for the Payee column, four multi-currency edge cases, per-region cheatsheet (UK, EU, US, AU, India, LatAm, SG, UAE), the mapping table from Xero's vague errors to the actual cause and fix, where the import button actually lives in Xero's 2026 UI, two worked examples (EUR account and a UK Money-In/Money-Out merge from Lloyds-style source), how Xero's Date+Amount+Description duplicate detection actually works, four strategies for safe re-imports across overlapping periods, the same-day double-charge edge case, the Demo Company test pattern for unfamiliar bank CSVs, the delete-and-replace recovery workflow for bad imports, batch import patterns for multi-client practices, the Analysis Code column and chart-of-accounts tagging, Bank Rules vs Contact suggestions vs Cash coding (when to use which), the Xero edition matrix (Starter/Standard/Premium/Cashbook/Ledger) and what changes per plan, a six-step diagnostic checklist for 'successful' imports that are actually wrong, the Statement Lines vs Bank Statements distinction (the deletable record, the reconciled-lines persistence rule, the bank-feed-to-CSV migration ghost-duplicate trap), the Lock Date + MTD digital-link workflow (split-at-the-boundary vs temporary-rollback, HMRC's manual-transcription rule, EU SDI/Chorus Pro/VeriFactu equivalents, the ~1000-line per-file cap and the half-month split pattern), the conversion-balance vs opening-balance vs first-imported-row trap that breaks new Xero orgs on day one (three-balance audit, retroactive backfill vs adjusting journal), the advanced Bank Rules playbook (AND/OR conditional matching, percentage splits, reference-driven contact matching, priority-order discipline, the Find & Recode + new-rule revenue re-allocation warning), the Find & Recode + Cash Coding post-import cleanup loop (when to use which, the cadence that keeps lines in the Cash Coding grid, the Adviser-menu Find & Recode for retro-fixing reconciled coding errors), the payment-processor playbook for Stripe (gross/fee/net split), PayPal (per-currency CSV split with Balance Affecting column), Wise (FX-conversion transfer pairing) and GoCardless (the two-leg pattern), and a copy-paste CSV template.

Read
bank-statement-converterquickbooks

Import bank statements into QuickBooks Online: a 2026 step-by-step walkthrough

The practical walkthrough: the four routes into QBO (live feed, .qbo, .qfx, CSV), why PDF is never one of them, where Intuit hid the upload button after the 2025 redesign, the Receipts vs Bank-transactions sidebar trap, the six-step PDF → .qbo → upload recipe, a worked Chase Business Checking example (87 transactions, six-minute close), the four pre-upload checks that catch a wrong-but-not-broken import (opening + Σ = closing, transaction count, date range, top-five spot-check), the live-feed vs file-upload decision tree, the CSV fallback and why you almost never want it, three multi-currency traps (mixed-currency statements, sub-currency tokens, home-currency rounding), per-bank quirks for Chase, Wells Fargo, HSBC, AIB, Revolut Business, HDFC/ICICI/SBI, three batch patterns for accountants (sequential pipeline, per-client reconciliation gate, API automation), and the seven-minute monthly-close time budget.

Read
bank-statement-converterquickbooks

How to back-fill QuickBooks Online with months of historical bank statements (2026)

The four scenarios that force a back-fill (new books, platform migration, neglected books, inherited client), why oldest-first month-by-month reconciliation is non-negotiable, how to anchor the opening balance to the prior statement's closing balance (not the next statement's opening), the FITID dedupe seam between live bank feed and historical .qbo uploads, closed-period locks and the prior-accountant question, multi-currency back-fill with historical FX rates and the home-currency rounding trap, the worked example (twelve months of Chase Business Checking, five-hour time budget), the per-month reconciliation loop with three concrete fixes for non-zero differences, practitioner-mode interleaving across multiple new clients, when to stop back-filling and rebuild the file instead, and the five artefacts that define a clean done state.

Read