<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vincent</title>
    <description>The latest articles on DEV Community by Vincent (@highfiddle).</description>
    <link>https://dev.to/highfiddle</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4220248%2F7b964c44-a004-4330-95d4-8a81bd568a32.png</url>
      <title>DEV Community: Vincent</title>
      <link>https://dev.to/highfiddle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/highfiddle"/>
    <language>en</language>
    <item>
      <title>The 18 FEC columns and the 10 errors that fail a French tax audit</title>
      <dc:creator>Vincent</dc:creator>
      <pubDate>Sun, 01 Nov 2026 12:20:33 +0000</pubDate>
      <link>https://dev.to/highfiddle/the-18-fec-columns-and-the-10-errors-that-fail-a-french-tax-audit-28g5</link>
      <guid>https://dev.to/highfiddle/the-18-fec-columns-and-the-10-errors-that-fail-a-french-tax-audit-28g5</guid>
      <description>&lt;p&gt;Every French company that keeps its books on a computer must be able to hand the tax administration one file: the &lt;strong&gt;FEC&lt;/strong&gt;, &lt;em&gt;Fichier des Écritures Comptables&lt;/em&gt;. Accounting software exports it in one click, so everyone assumes it is correct.&lt;/p&gt;

&lt;p&gt;It often isn't. A FEC that is late or does not follow the required format costs a &lt;strong&gt;€5,000 fine&lt;/strong&gt; under article 1729 D of the French tax code (CGI). For a remote audit (&lt;em&gt;examen de comptabilité&lt;/em&gt;), 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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a FEC is
&lt;/h2&gt;

&lt;p&gt;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 &lt;em&gt;Livre des procédures fiscales&lt;/em&gt;, LPF). For a remote audit, it has 15 days from the notice. The format is fixed by &lt;strong&gt;article A47 A-1 LPF&lt;/strong&gt; and explained in the administration's guidance BOI-CF-IOR-60-40-20.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 18 columns
&lt;/h2&gt;

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

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

&lt;p&gt;A full line looks like this (pipe-separated):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VE|Ventes|000039|20250610|411000|Clients|CLI001|Atelier Durand|F2025-06|20250610|Facture F2025-06 Atelier Durand|3960,00|0,00|||20250610||
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  The 10 errors
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Wrong file name
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FEC_2025.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; &lt;code&gt;123456782FEC20251231.txt&lt;/code&gt; for SIREN 123456782 and a year closing on 31 December 2025. The text fixes the name, not the extension; &lt;code&gt;.txt&lt;/code&gt; 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.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Mixed or wrong separator
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it fails:&lt;/strong&gt; fields are separated by &lt;strong&gt;a tab or a pipe&lt;/strong&gt; (&lt;code&gt;|&lt;/code&gt;), 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 &lt;code&gt;field_count&lt;/code&gt; on line 5, and the entry then looks unbalanced because half of it cannot be read.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; 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.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Broken accents
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VE|Ventes|000002|20250310|411000|Clients|||F000002|20250310|Facture rÃ©glÃ©e|120,00|0,00|||20250310||
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it fails:&lt;/strong&gt; the allowed encodings are ASCII, ISO 8859-15 and UTF-8 (A47 A-1, XII). &lt;code&gt;rÃ©glÃ©e&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be aware:&lt;/strong&gt; 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 &lt;code&gt;Ã&lt;/code&gt; before sending it.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Misspelled or reordered headers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JournalCode|JournalLib|EcritureNum|DateEcriture|CompteNum|CompteLib|CompAuxNum|CompAuxLib|PieceRef|PieceDate|EcritureLib|Credit|Debit|EcritureLet|DateLet|ValidDate|Montantdevise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it fails:&lt;/strong&gt; three problems in one line. &lt;code&gt;DateEcriture&lt;/code&gt; instead of &lt;code&gt;EcritureDate&lt;/code&gt;, &lt;code&gt;Credit&lt;/code&gt; before &lt;code&gt;Debit&lt;/code&gt;, and &lt;code&gt;Idevise&lt;/code&gt; missing. The checker reports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; copy the header from the table above, exactly, case included. Empty optional columns stay in the header.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Dates not in AAAAMMJJ
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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||
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; 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.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Decimal point or thousands separators in amounts
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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||
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it fails:&lt;/strong&gt; the comma separates units from decimals, and &lt;strong&gt;no thousands separator is accepted&lt;/strong&gt; (A47 A-1, XII). &lt;code&gt;120.00&lt;/code&gt; and &lt;code&gt;1 200,00&lt;/code&gt; both fail.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  7. Unbalanced entries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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||
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it fails:&lt;/strong&gt; double-entry bookkeeping. The lines of one entry (same &lt;code&gt;EcritureNum&lt;/code&gt;) must have total debit = total credit, and so must the whole file. Here 3960,00 debit against 3860,00 credit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; 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.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Gaps or duplicates in EcritureNum
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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||
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it fails:&lt;/strong&gt; &lt;code&gt;EcritureNum&lt;/code&gt; 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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error num_gap x1: Numbering gap: 3 number(s) missing, from 47 to 49.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The sequence can be global or per journal (&lt;code&gt;VE0001&lt;/code&gt;, &lt;code&gt;AC0001&lt;/code&gt;…); 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; 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.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Missing ValidDate or validation out of order
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VE|Ventes|000002|20250310|411000|Clients|||F000002|20250310|Facture F1|120,00|0,00|||||
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it fails:&lt;/strong&gt; &lt;code&gt;ValidDate&lt;/code&gt; 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 &lt;code&gt;ValidDate&lt;/code&gt; means a draft entry was exported. Dates going backwards against the numbering are a red flag too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error validdate_not_chronological x1: Validation date earlier than that of entry no. 71 (20251020): validation must follow numbering order.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; validate (close) the draft entries for the year in the software, then export again.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Opening entries missing or misplaced
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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||
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it fails:&lt;/strong&gt; the file must include the entries that record the opening balance sheet (&lt;em&gt;à-nouveaux&lt;/em&gt;), 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.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  A 20-line header check in Python
&lt;/h2&gt;

&lt;p&gt;The header causes a large share of rejections and is the easiest thing to check. This is the header logic of &lt;code&gt;fec-lint&lt;/code&gt;, reduced to plain Python with no dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;EXPECTED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;JournalCode&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;JournalLib&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;EcritureNum&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;EcritureDate&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CompteNum&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CompteLib&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CompAuxNum&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CompAuxLib&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PieceRef&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PieceDate&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;EcritureLib&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Debit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Credit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;EcritureLet&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DateLet&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ValidDate&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Montantdevise&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Idevise&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readline&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;lstrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;﻿&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;rstrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sep&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;no tab or pipe separator in the header&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sep&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; columns instead of 18&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;missing column: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;EXPECTED&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;unknown column: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;EXPECTED&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;EXPECTED&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;EXPECTED&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;columns are not in the required order&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the header from error 4 it returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;17 columns instead of 18
missing column: EcritureDate
missing column: Idevise
unknown column: DateEcriture
columns are not in the required order
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  How to check your own file
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test Compta Demat&lt;/strong&gt;, the administration's free tool, checks the file the way the DGFiP reads it. Start there; it is the reference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fec-lint&lt;/strong&gt;, free and open source (MIT): errors 1, 2, 4, 5 and 6, a UTF-16 file for error 3 and an empty &lt;code&gt;ValidDate&lt;/code&gt; 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.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  pipx &lt;span class="nb"&gt;install &lt;/span&gt;fec-lint
  fec-lint 123456782FEC20251231.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FEC Checker&lt;/strong&gt;, 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: &lt;a href="https://apify.com/highfiddle/fec-checker" rel="noopener noreferrer"&gt;FEC Checker on Apify&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these replaces reading the first and last lines of the file yourself, especially for errors 3 and 10.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;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).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>accounting</category>
      <category>france</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
