Skip to content

Fix Odoo Bank Statement Import Errors: OFX, CSV, CAMT, and MT940 Issues

DeployMonkey Team · March 23, 2026 11 min read

The Bank Statement Import Problem

Importing bank statements is a daily task for accounting teams using Odoo. When the import fails — wrong format, encoding issues, or data mismatches — bank reconciliation is blocked and accounting work piles up.

Common Import Errors

# Format errors:
UserError: "Unable to determine the format of the file"
UserError: "Could not read the bank statement file"

# Data errors:
UserError: "The journal currency and the bank statement currency must be the same"
ValidationError: "The bank account number does not match any journal"

# Duplicate errors:
UserError: "A bank statement with the same reference already exists"

# Encoding errors:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0

Supported Formats

Odoo supports multiple bank statement formats. Each requires a specific module:

FormatModuleCommon Banks
OFX/QFXaccount_bank_statement_import_ofxUS/Canada banks
CAMT.053account_bank_statement_import_camtEuropean banks (SEPA)
MT940account_bank_statement_import_mt940SWIFT network banks
CSVaccount_bank_statement_import_csvAny bank (manual export)
QIFaccount_bank_statement_import_qifQuicken/older US banks

Fix 1: Install the Correct Module

# Error: "Unable to determine the format of the file"

# Fix: Install the matching import module
# Settings → Apps → search for "bank statement import"
# Install the module matching your file format

# Check file format:
# .ofx / .qfx → OFX format
# .xml with CAMT tags → CAMT.053
# .sta / .940 → MT940
# .csv → CSV (needs mapping)
# .qif → QIF format

Fix 2: Currency Mismatch

# Error: "The journal currency and the bank statement currency must be the same"

# Fix: Check journal currency matches statement currency
# Accounting → Configuration → Journals → Bank journal
# Currency field must match the currency in your bank statement

# If your bank sends EUR but your journal is USD:
# Option 1: Create a separate journal for EUR bank account
# Option 2: Convert the statement to USD before importing

# Check statement currency (for XML formats):
grep -i 'ccy\|currency' your_statement.xml | head -5

Fix 3: Account Number Mismatch

# Error: "The bank account number does not match any journal"

# The IBAN or account number in the file doesn't match any bank journal

# Fix:
# 1. Check the account number in your file:
grep -i 'acctid\|iban\|account' your_statement.* | head -5

# 2. Set the same account number on the bank journal:
# Accounting → Configuration → Journals → Bank journal
# Bank Account → Account Number / IBAN → enter the exact number from the file

# Common issue: spaces or formatting differences
# File has: "NL91 ABNA 0417 1643 00"
# Journal has: "NL91ABNA0417164300"
# Odoo normalizes IBANs, but non-IBAN formats must match exactly

Fix 4: Duplicate Statement Detection

# Error: "A bank statement with the same reference already exists"

# Odoo prevents importing the same statement twice

# Fix Option 1: Delete the existing statement
# Accounting → Bank Statements → find the duplicate → delete
# Note: only unreconciled statements can be deleted

# Fix Option 2: Edit the file to change the statement reference
# OFX: change the <STMTTRN><FITID> values
# CAMT: change the <Stmt><Id> value

# Fix Option 3: Disable duplicate detection (not recommended)
# This is generally not advisable as it creates duplicate entries

Fix 5: CSV Import Mapping

CSV imports require column mapping since CSV has no standard format.

# Required CSV columns:
# - Date (transaction date)
# - Amount (positive for credits, negative for debits — or separate columns)
# - Label/Memo (transaction description)

# Optional but useful:
# - Reference (bank reference number)
# - Partner Name

# Common issues:
# 1. Date format mismatch: use YYYY-MM-DD or MM/DD/YYYY
# 2. Decimal separator: Odoo expects period (.) not comma (,)
#    Fix: Find & replace in the CSV before importing
# 3. Amount sign: Some banks use separate Debit/Credit columns
#    You may need to combine them into a single Amount column

# Example working CSV:
# Date,Label,Amount,Reference
# 2026-03-01,"Payment from Customer",1500.00,REF001
# 2026-03-02,"Office Supplies",-250.50,REF002

Fix 6: File Encoding Issues

# Error: UnicodeDecodeError

# Many European banks export files in Latin-1 or Windows-1252 encoding

# Fix: Convert to UTF-8 before importing:
iconv -f ISO-8859-1 -t UTF-8 statement.csv > statement_utf8.csv

# Or for Windows encoding:
iconv -f WINDOWS-1252 -t UTF-8 statement.csv > statement_utf8.csv

# Check current encoding:
file -bi statement.csv

Fix 7: OFX Parsing Errors

# Error: "Could not read the bank statement file" for .ofx files

# Some banks produce malformed OFX files

# Fix 1: Check OFX version
# OFX 1.x (SGML) vs OFX 2.x (XML) — Odoo handles both
# but some banks produce hybrid files

# Fix 2: Common OFX issues:
# - Missing closing tags: </STMTTRN>
# - Invalid characters in MEMO fields
# - Truncated file (download interrupted)

# Fix 3: Use an OFX converter
# Convert OFX to CSV using a tool like ofxparse:
pip install ofxparse
python3 -c "
from ofxparse import OfxParser
with open('statement.ofx', 'rb') as f:
    ofx = OfxParser.parse(f)
for txn in ofx.account.statement.transactions:
    print(f'{txn.date},{txn.payee},{txn.amount}')
" > statement.csv

Fix 8: CAMT.053 Namespace Issues

# Some banks use older CAMT versions or non-standard namespaces

# Check the namespace in your XML file:
head -5 statement.xml
# Should contain: urn:iso:std:iso:20022:tech:xsd:camt.053.001.XX

# If the namespace version does not match Odoo's expectation:
# Edit the file to update the namespace
# Or install a localization module that supports your bank's format

Debugging Import Failures

# 1. Enable debug mode and check the full error traceback
# ?debug=1 in URL → import → check error details

# 2. Try importing a small subset
# For CSV: keep header + first 3 transactions
# For OFX/CAMT: this is harder, try a different export date range

# 3. Check Odoo logs:
grep -i 'bank.*statement\|import.*error' /var/log/odoo/odoo-server.log | tail -20