DEV Community

Cover image for The 18 FEC columns and the 10 errors that fail a French tax audit
Vincent
Vincent

Posted on

The 18 FEC columns and the 10 errors that fail a French tax audit

Every French company that keeps its books on a computer must be able to hand the tax administration one file: the FEC, Fichier des Écritures Comptables. Accounting software exports it in one click, so everyone assumes it is correct.

It often isn't. A FEC that is late or does not follow the required format costs a €5,000 fine under article 1729 D of the French tax code (CGI). For a remote audit (examen de comptabilité), the administration's own guidance, updated in January 2026, applies it once per audit (BOI-CF-DG-40-20 § 390). Worse than the fine, a file the auditor cannot read is a bad start to an audit.

This guide lists the 18 columns, then ten errors I see in real exports, each with a bad line, why it fails and the fix. Every example below comes from synthetic files and from the output of two checkers I wrote; the rules are checked against the official text.

What a FEC is

Since 2014, a company under audit must hand over its accounting entries as a file at the start of the audit (article L47 A of the Livre des procédures fiscales, LPF). For a remote audit, it has 15 days from the notice. The format is fixed by article A47 A-1 LPF and explained in the administration's guidance BOI-CF-IOR-60-40-20.

The file holds every entry recorded during the fiscal year, opening balances included, one line per entry line. Most companies send a flat text file; an XML format also exists, but this guide covers the flat file.

The 18 columns

For a company taxed on commercial profits (BIC or corporate tax), the file has exactly these 18 columns, in this order. Cash-basis non-commercial and agricultural filers add columns (22 and 21); they are out of scope here.

# Column Content Example
1 JournalCode Journal code VE
2 JournalLib Journal name Ventes
3 EcritureNum Entry number, on a continuous sequence 000039
4 EcritureDate Accounting date, AAAAMMJJ 20250610
5 CompteNum Account number 411000
6 CompteLib Account name Clients
7 CompAuxNum Sub-ledger account (customer, supplier); may be empty CLI001
8 CompAuxLib Sub-ledger account name; filled when 7 is Atelier Durand
9 PieceRef Supporting document reference F2025-06
10 PieceDate Document date, AAAAMMJJ 20250610
11 EcritureLib Entry label Facture F2025-06 Atelier Durand
12 Debit Debit amount, decimal comma 3960,00
13 Credit Credit amount, decimal comma 0,00
14 EcritureLet Matching (lettrage) code; may be empty AA
15 DateLet Matching date; filled when 14 is 20250712
16 ValidDate Date the entry was validated 20250610
17 Montantdevise Amount in foreign currency; may be empty 1200,00
18 Idevise Currency code; filled when 17 is USD

A full line looks like this (pipe-separated):

VE|Ventes|000039|20250610|411000|Clients|CLI001|Atelier Durand|F2025-06|20250610|Facture F2025-06 Atelier Durand|3960,00|0,00|||20250610||
Enter fullscreen mode Exit fullscreen mode

If your software has no separate debit and credit, the text allows Montant and Sens (D/C or +1/-1) instead of columns 12 and 13. Most exports use Debit/Credit.

The 10 errors

1. Wrong file name

FEC_2025.txt
Enter fullscreen mode Exit fullscreen mode

Why it fails: the name is part of the format: the company's SIREN, the letters FEC, then the fiscal year's closing date as AAAAMMJJ (A47 A-1, IX).

Fix: 123456782FEC20251231.txt for SIREN 123456782 and a year closing on 31 December 2025. The text fixes the name, not the extension; .txt is the usual choice for the flat file. Also check that the SIREN is right: it has a Luhn check digit, so a typo is often detectable.

2. Mixed or wrong separator

VE|Ventes|000002|20250310|411000|Clients|||F000002|20250310|Facture F1|120,00|0,00|||20250310||
VE;Ventes;000002;20250310;706000;Prestations;;;F000002;20250310;Facture F1;0,00;120,00;;;20250310;;
Enter fullscreen mode Exit fullscreen mode

Why it fails: fields are separated by a tab or a pipe (|), the same one for the whole file (A47 A-1, VI). Semicolons, the default of many spreadsheets in France, are not allowed. The second line above has 1 field instead of 18 for a pipe reader, so the checker reports field_count on line 5, and the entry then looks unbalanced because half of it cannot be read.

Fix: export the FEC from the accounting software, never through a spreadsheet. If you must edit it, save as "text (tab-separated)" and check that no label contains the separator.

3. Broken accents

VE|Ventes|000002|20250310|411000|Clients|||F000002|20250310|Facture réglée|120,00|0,00|||20250310||
Enter fullscreen mode Exit fullscreen mode

Why it fails: the allowed encodings are ASCII, ISO 8859-15 and UTF-8 (A47 A-1, XII). réglée is "réglée" encoded twice: someone opened a UTF-8 file as Latin-1 and saved it as UTF-8 again. The labels are now wrong in the copy the auditor reads.

Fix: pick one encoding and never re-save the file in a text editor or spreadsheet. A file in UTF-16 ("Unicode text" in Excel) is outside the list too: re-export it as UTF-8.

Be aware: no automatic check can be sure here. A double-encoded label is still valid UTF-8, so both tools below accept it. Search the file for à before sending it.

4. Misspelled or reordered headers

JournalCode|JournalLib|EcritureNum|DateEcriture|CompteNum|CompteLib|CompAuxNum|CompAuxLib|PieceRef|PieceDate|EcritureLib|Credit|Debit|EcritureLet|DateLet|ValidDate|Montantdevise
Enter fullscreen mode Exit fullscreen mode

Why it fails: three problems in one line. DateEcriture instead of EcritureDate, Credit before Debit, and Idevise missing. The checker reports:

error header_count x1: The header must contain exactly 18 columns.
error header_missing x2: Mandatory column missing from the header: EcritureDate.
error header_unknown x1: Header column not defined by article A47 A-1.
error header_order x1: The header columns are not in the required order.
Enter fullscreen mode Exit fullscreen mode

Fix: copy the header from the table above, exactly, case included. Empty optional columns stay in the header.

5. Dates not in AAAAMMJJ

AC|Achats|000009|20250230|613200|Locations immobilieres|||FL02|20250205|Facture FL02 SCI Les Tilleuls|1200,00|0,00|||20250205||
AC|Achats|000026|12/04/2025|626000|Frais postaux et telecom|||FT04|20250411|Facture FT04 Telecom Ouest|89,90|0,00|||20250411||
Enter fullscreen mode Exit fullscreen mode

Why it fails: dates are AAAAMMJJ with no separator (A47 A-1, XII). 12/04/2025 has the wrong format. 20250230 has the right format but does not exist (there is no 30 February), which a format check alone misses:

error date_invalid x3: Non-existent date in EcritureDate. - line(s) 21, 22, 23
error date_format x3: Wrong date format in EcritureDate (expected AAAAMMJJ). - line(s) 64, 65, 66
Enter fullscreen mode Exit fullscreen mode

Fix: set the export's date format in the software. A non-existent date usually comes from a manual entry: correct the entry, then export again.

6. Decimal point or thousands separators in amounts

VE|Ventes|000002|20250310|411000|Clients|||F000002|20250310|Facture F1|120.00|0,00|||20250310||
VE|Ventes|000002|20250310|411000|Clients|||F000002|20250310|Facture F1|1 200,00|0,00|||20250310||
Enter fullscreen mode Exit fullscreen mode

Why it fails: the comma separates units from decimals, and no thousands separator is accepted (A47 A-1, XII). 120.00 and 1 200,00 both fail.

Fix: 120,00 and 1200,00. One detail people get wrong in the other direction: a negative amount may carry its sign as the first character on the left or the last on the right (-150,00 or 150,00-), both are legal.

7. Unbalanced entries

VE|Ventes|000039|20250610|411000|Clients|CLI001|Atelier Durand|F2025-06|20250610|Facture F2025-06 Atelier Durand|3960,00|0,00|||20250610||
VE|Ventes|000039|20250610|706000|Prestations de services|||F2025-06|20250610|Facture F2025-06 Atelier Durand|0,00|3200,00|||20250610||
VE|Ventes|000039|20250610|445710|TVA collectee|||F2025-06|20250610|Facture F2025-06 Atelier Durand|0,00|660,00|||20250610||
Enter fullscreen mode Exit fullscreen mode

Why it fails: double-entry bookkeeping. The lines of one entry (same EcritureNum) must have total debit = total credit, and so must the whole file. Here 3960,00 debit against 3860,00 credit:

error entry_unbalanced x1: Unbalanced entry: debit - credit difference of 100,00.
error file_unbalanced x1: The file is unbalanced: total debit 193104,48, total credit 193004,48, difference 100,00.
Enter fullscreen mode Exit fullscreen mode

Fix: software does not book unbalanced entries, so this almost always means the export lost or changed lines: a filter on accounts, a truncated label that shifted a column, or a manual edit. Find the entry by its number and compare with the ledger.

8. Gaps or duplicates in EcritureNum

AC|Achats|000046|20250704|401000|Fournisseurs|FOU002|SCI Les Tilleuls|FL07|20250704|Facture FL07 SCI Les Tilleuls|0,00|1440,00|||20250704||
VE|Ventes|000050|20250710|411000|Clients|CLI002|Boulangerie Martin|F2025-07|20250710|Facture F2025-07 Boulangerie Martin|4140,00|0,00|||20250710||
Enter fullscreen mode Exit fullscreen mode

Why it fails: EcritureNum is "the number on a continuous sequence" (A47 A-1, VII). Entries 47 to 49 are missing, which is exactly what an auditor looks for: deleted entries.

error num_gap x1: Numbering gap: 3 number(s) missing, from 47 to 49.
Enter fullscreen mode Exit fullscreen mode

The sequence can be global or per journal (VE0001, AC0001…); a checker has to work out which one the file uses before counting gaps. The same number used twice for two different entries is the opposite error.

Fix: if entries were really deleted, the file shows it and you need an explanation. More often, the export left out a journal or a period: export the whole fiscal year, all journals.

9. Missing ValidDate or validation out of order

VE|Ventes|000002|20250310|411000|Clients|||F000002|20250310|Facture F1|120,00|0,00|||||
Enter fullscreen mode Exit fullscreen mode

Why it fails: ValidDate is the date the entry became final and can no longer be changed. The file is sorted in chronological order of validation (A47 A-1, VII), so an empty ValidDate means a draft entry was exported. Dates going backwards against the numbering are a red flag too:

error validdate_not_chronological x1: Validation date earlier than that of entry no. 71 (20251020): validation must follow numbering order.
Enter fullscreen mode Exit fullscreen mode

Fix: validate (close) the draft entries for the year in the software, then export again.

10. Opening entries missing or misplaced

VE|Ventes|000001|20250310|411000|Clients|||F000001|20250310|Facture F1|120,00|0,00|||20250310||
VE|Ventes|000001|20250310|706000|Prestations|||F000001|20250310|Facture F1|0,00|120,00|||20250310||
AN|A-nouveaux|000002|20250101|512000|Banque|||AN2025|20250101|Reprise des soldes|15000,00|0,00|||20250315||
AN|A-nouveaux|000002|20250101|101000|Capital|||AN2025|20250101|Reprise des soldes|0,00|15000,00|||20250315||
Enter fullscreen mode Exit fullscreen mode

Why it fails: the file must include the entries that record the opening balance sheet (à-nouveaux), and they normally take the first entry numbers of the year (A47 A-1, VII). The administration accepts them later in the file only if they cannot come first and the auditor can still identify them (BOI-CF-IOR-60-40-20). A file with no opening entries at all does not let the auditor check the balances.

Fix: include the opening journal (usually AN) in the export and number it first. Be aware: I know of no automatic checker, including mine, that verifies this today; check it by eye in the first lines of the file.

A 20-line header check in Python

The header causes a large share of rejections and is the easiest thing to check. This is the header logic of fec-lint, reduced to plain Python with no dependency:

EXPECTED = ['JournalCode', 'JournalLib', 'EcritureNum', 'EcritureDate', 'CompteNum', 'CompteLib',
            'CompAuxNum', 'CompAuxLib', 'PieceRef', 'PieceDate', 'EcritureLib', 'Debit', 'Credit',
            'EcritureLet', 'DateLet', 'ValidDate', 'Montantdevise', 'Idevise']


def check_header(path, encoding='utf-8'):
    with open(path, encoding=encoding) as f:
        header = f.readline().lstrip('').rstrip('\r\n')
    sep = '\t' if '\t' in header else '|' if '|' in header else None
    if sep is None:
        return ['no tab or pipe separator in the header']
    names = [n.strip() for n in header.split(sep)]
    errors = []
    if len(names) != 18:
        errors.append(f'{len(names)} columns instead of 18')
    errors += [f'missing column: {n}' for n in EXPECTED if n not in names]
    errors += [f'unknown column: {n}' for n in names if n not in EXPECTED]
    found = [n for n in names if n in EXPECTED]
    if found != [n for n in EXPECTED if n in found]:
        errors.append('columns are not in the required order')
    return errors
Enter fullscreen mode Exit fullscreen mode

On the header from error 4 it returns:

17 columns instead of 18
missing column: EcritureDate
missing column: Idevise
unknown column: DateEcriture
columns are not in the required order
Enter fullscreen mode Exit fullscreen mode

Two details matter. The order check compares only the columns that were found, so a missing column does not hide a swap. And lstrip('') removes the byte-order mark some Windows tools add, which would otherwise make the first column JournalCode.

How to check your own file

  • Test Compta Demat, the administration's free tool, checks the file the way the DGFiP reads it. Start there; it is the reference.
  • fec-lint, free and open source (MIT): errors 1, 2, 4, 5 and 6, a UTF-16 file for error 3 and an empty ValidDate for error 9, as a command line tool and an MCP server for AI assistants. It runs on your machine and the file never leaves it.
  pipx install fec-lint
  fec-lint 123456782FEC20251231.txt
Enter fullscreen mode Exit fullscreen mode
  • FEC Checker, the full pre-audit: everything above plus balance, numbering, validation order, risk signals (weekend postings, round amounts, Benford's law, cash and suspense accounts) and an optional AI-written fix list, in French or English: FEC Checker on Apify.

None of these replaces reading the first and last lines of the file yourself, especially for errors 3 and 10.


Technical guide, not tax advice. It describes the published file format; it does not tell you how the administration will judge your accounts. For that, ask your accountant (expert-comptable).

Top comments (0)