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à.
<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.
<rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<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.
<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.
<ram:SpecifiedTradeSettlementPaymentMeans>
<ram:TypeCode>30</ram:TypeCode>
</ram:SpecifiedTradeSettlementPaymentMeans>
<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é.
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount>75.70</ram:LineTotalAmount> <!-- 69.80 + 5.90 -->
<ram:TaxBasisTotalAmount>75.70</ram:TaxBasisTotalAmount>
…
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<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.