Accueil › Guides

Erreurs du validateur Factur-X : causes et corrections

Votre XML passe le schéma mais le validateur le déclare invalide ? Voici les erreurs que nous avons rencontrées en construisant FacturConforme, ce qui les provoque, et le XML qui les corrige.

Mis à jour le 17 septembre 2026

Schéma valide, facture invalide : pourquoi

Un validateur Factur-X contrôle deux choses. Le schéma XSD vérifie la structure : les bons éléments, au bon endroit, avec le bon type. Le Schematron vérifie le sens : les totaux s’additionnent, les informations obligatoires sont là, les codes sont cohérents entre eux.

La France ajoute ses propres règles par-dessus celles de la norme européenne EN 16931. Elles portent le préfixe BR-FR. Un fichier peut donc être parfaitement conforme à EN 16931 et rejeté pour la France.

Les numéros de règles françaises ne sont pas figés : ils ont évolué d’une version des jeux de règles à l’autre, et deux outils peuvent donner des numéros différents pour le même manque. Les codes ci-dessous sont ceux renvoyés par le validateur en ligne du FNFE-MPE fin août 2026. Fiez-vous d’abord au terme métier cité dans le message (BT-22, BT-34…), il est stable.

Les extraits sont au format CII, la syntaxe du XML embarqué dans une facture Factur-X. Seuls les éléments utiles sont montrés.

BR-FR-05 : mentions obligatoires absentes

Ce qui manque. Le droit commercial français impose trois mentions sur les factures entre professionnels : les pénalités de retard, l’indemnité forfaitaire de 40 € pour frais de recouvrement, et les conditions d’escompte. Dans le fichier, chacune doit figurer dans une note du document (BT-22), avec son code : PMD, PMT et AAB.

Le piège. Écrire ces mentions dans le PDF ou dans un champ de texte libre ne suffit pas. Sans le code, le validateur ne sait pas qu’elles sont là.

Correction : trois notes codées dans l’en-tête du document
<rsm:ExchangedDocument>
  <ram:ID>FA-2026-00157</ram:ID>
  <ram:TypeCode>380</ram:TypeCode>
  <ram:IssueDateTime>…</ram:IssueDateTime>
  <ram:IncludedNote>
    <ram:Content>En cas de retard de paiement, des pénalités sont exigibles…</ram:Content>
    <ram:SubjectCode>PMD</ram:SubjectCode>
  </ram:IncludedNote>
  <ram:IncludedNote>
    <ram:Content>Tout retard de paiement donne lieu à une indemnité forfaitaire
      pour frais de recouvrement de 40 euros (article L. 441-10 du code de commerce).</ram:Content>
    <ram:SubjectCode>PMT</ram:SubjectCode>
  </ram:IncludedNote>
  <ram:IncludedNote>
    <ram:Content>Aucun escompte n'est accordé pour paiement anticipé.</ram:Content>
    <ram:SubjectCode>AAB</ram:SubjectCode>
  </ram:IncludedNote>
</rsm:ExchangedDocument>

BR-FR-08 : cadre de facturation absent

Ce qui manque. Le cadre de facturation (BT-23), qui dit notamment si la facture porte sur des biens, des services ou les deux. Il se place dans le contexte du document, avant l’identifiant du profil.

Pour une facture ordinaire, trois valeurs suffisent : B1 pour une livraison de biens, S1 pour une prestation de services, M1 pour une opération mixte. La liste en compte d’autres pour des cas particuliers.

Avant : seul le profil est déclaré
<rsm:ExchangedDocumentContext>
  <ram:GuidelineSpecifiedDocumentContextParameter>
    <ram:ID>urn:cen.eu:en16931:2017</ram:ID>
  </ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
Après : le cadre de facturation vient en premier
<rsm:ExchangedDocumentContext>
  <ram:BusinessProcessSpecifiedDocumentContextParameter>
    <ram:ID>B1</ram:ID>
  </ram:BusinessProcessSpecifiedDocumentContextParameter>
  <ram:GuidelineSpecifiedDocumentContextParameter>
    <ram:ID>urn:cen.eu:en16931:2017</ram:ID>
  </ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>

Bon à savoir. Cette information recoupe la « catégorie de l’opération », l’une des nouvelles mentions obligatoires de la réforme. Si votre outil la calcule déjà, il suffit de la reporter ici.

BR-FR-12 et BR-FR-13 : adresses électroniques absentes

Ce qui manque. L’adresse électronique de l’acheteur (BT-49, BR-FR-12) et celle du vendeur (BT-34, BR-FR-13). Ce n’est pas une adresse de courriel : c’est l’identifiant qui permet d’acheminer la facture vers la bonne plateforme. En France, il repose sur le SIREN, déclaré avec le schéma 0225.

Correction : dans la partie vendeur comme dans la partie acheteur, après l’adresse postale
<ram:BuyerTradeParty>
  <ram:Name>Atelier Kerlann</ram:Name>
  <ram:SpecifiedLegalOrganization>
    <ram:ID schemeID="0002">123456782</ram:ID>
  </ram:SpecifiedLegalOrganization>
  <ram:PostalTradeAddress>…</ram:PostalTradeAddress>
  <ram:URIUniversalCommunication>
    <ram:URIID schemeID="0225">123456782</ram:URIID>
  </ram:URIUniversalCommunication>
</ram:BuyerTradeParty>

Le même SIREN apparaît deux fois, avec deux schémas : 0002 pour l’identifiant légal de l’entreprise, 0225 pour son adresse de routage. Ce n’est pas un doublon, ce sont deux usages distincts.

Le cas qui révèle un problème de conception. Si l’acheteur est un particulier, il n’a pas de SIREN, donc pas d’adresse électronique : l’erreur est impossible à corriger honnêtement. La vraie réponse est ailleurs. Une vente à un particulier ne relève pas de la facture électronique mais de l’e-reporting, et ne devrait pas produire ce fichier du tout. Inventer un identifiant pour faire taire le validateur produirait un document faux.

CII-SR-470 : virement sans IBAN

Ce qui manque. Le compte à créditer. Quand la facture annonce un règlement par virement (code 30) ou par virement SEPA (code 58), elle doit donner l’IBAN du bénéficiaire (BT-84). La norme européenne pose la même exigence dans sa règle BR-61.

Avant : un virement sans compte
<ram:SpecifiedTradeSettlementPaymentMeans>
  <ram:TypeCode>30</ram:TypeCode>
</ram:SpecifiedTradeSettlementPaymentMeans>
Après : l’IBAN du vendeur accompagne le code
<ram:SpecifiedTradeSettlementPaymentMeans>
  <ram:TypeCode>30</ram:TypeCode>
  <ram:PayeePartyCreditorFinancialAccount>
    <ram:IBANID>FR7630001007941234567890185</ram:IBANID>
  </ram:PayeePartyCreditorFinancialAccount>
</ram:SpecifiedTradeSettlementPaymentMeans>

Le mauvais réflexe. Remplacer le code 30 par un autre moyen de paiement pour faire disparaître l’erreur. Le fichier passe, mais il affirme un mode de règlement qui n’est pas le vrai. Si vous ne connaissez pas le moyen de paiement, le code 1 (instrument non défini) dit exactement cela, sans rien inventer.

BR-CO-10 : total des lignes incohérent

La règle. Le total des lignes du document (BT-106) doit être égal à la somme des montants nets de chaque ligne (BT-131). Dit comme ça, c’est une évidence. L’erreur vient presque toujours du port.

La cause. Dans une boutique en ligne, le port ressemble à une ligne de commande, et on est tenté de l’ajouter au total des lignes. Mais la norme ne le traite pas comme une ligne : c’est une charge de niveau document. Le compter dans le total des lignes sans créer de ligne correspondante casse l’égalité.

Avant : le port de 5,90 € est ajouté au total des lignes
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
  <ram:LineTotalAmount>75.70</ram:LineTotalAmount>  <!-- 69.80 + 5.90 -->
  <ram:TaxBasisTotalAmount>75.70</ram:TaxBasisTotalAmount>
  …
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
Après : le port devient une charge, et les totaux la font apparaître
<ram:SpecifiedTradeAllowanceCharge>
  <ram:ChargeIndicator>
    <udt:Indicator>true</udt:Indicator>
  </ram:ChargeIndicator>
  <ram:ActualAmount>5.90</ram:ActualAmount>
  <ram:Reason>Colissimo</ram:Reason>
  <ram:CategoryTradeTax>
    <ram:TypeCode>VAT</ram:TypeCode>
    <ram:CategoryCode>S</ram:CategoryCode>
    <ram:RateApplicablePercent>20.00</ram:RateApplicablePercent>
  </ram:CategoryTradeTax>
</ram:SpecifiedTradeAllowanceCharge>
…
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
  <ram:LineTotalAmount>69.80</ram:LineTotalAmount>
  <ram:ChargeTotalAmount>5.90</ram:ChargeTotalAmount>
  <ram:TaxBasisTotalAmount>75.70</ram:TaxBasisTotalAmount>
  …
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>

La base imposable, elle, ne change pas : total des lignes, plus les charges, moins les remises. N’oubliez pas la TVA du port dans la ventilation par taux : elle entre dans la base du taux concerné.

Même logique pour les remises. Une remise sur la commande entière s’écrit en charge avec ChargeIndicator à false, et apparaît dans AllowanceTotalAmount. Une charge négative n’est pas une remise.

Sur WooCommerce, sans écrire de XML. L’extension gratuite FacturConforme produit un XML qui respecte déjà chacune de ces règles, et vérifie avant d’émettre que la commande contient les informations nécessaires.