Si vous envoyez des factures électroniques à un client B2B allemand en 2026, le fichier est conforme ZUGFeRD ou il est rejeté à la réception. Même logique en France avec Factur-X. Le format est une enveloppe PDF/A-3 avec un XML CII EN 16931 joint ; le générer à partir de zéro n’est pas trivial, et le valider exige un moteur de référence.
En pratique, ce moteur est Mustang (mustangproject.org) : un projet Java open source qui extrait le XML embarqué d’un PDF/A-3 et le valide avec EN 16931 Schematron. Mustang offre le support le plus avancé de ZUGFeRD et Factur-X parmi les outils open source, et c’est le moteur que beaucoup de vérificateurs indépendants exécutent.
Cet article passe en revue les échecs que Mustang signale, ainsi qu’une manière plus rapide de l’exécuter.
Ce que Mustang vérifie réellement
Quand vous donnez un PDF Factur-X ou ZUGFeRD à Mustang, il fait à peu près ceci :
- Extraire le fichier embarqué. PDF/A-3 stocke les pièces jointes dans l’arborescence de noms
/EmbeddedFiles. Mustang cherche le nom canonique (factur-x.xmlpour Factur-X,zugferd-invoice.xmlpour ZUGFeRD 2.x) et récupère les octets. - Vérifier AFRelationship. Le fichier joint doit être déclaré avec
AFRelationship="Alternative"selon le socle Factur-X / ZUGFeRD. Toute autre valeur (Source,Data,Supplement) échoue. - Vérifier l’espace de noms XMP et la version. Factur-X 1.0 utilise
urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#. ZUGFeRD 2.x utiliseurn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#. Un espace de noms ou une chaîne de version erroné échoue. - Analyser le XML comme Cross-Industry Invoice (CII). Il doit être bien formé et commencer par le bon élément racine CII (
rsm:CrossIndustryInvoice). - Exécuter EN 16931 Schematron. C’est le cœur de la validation : environ 200 règles métier couvrant la sémantique des champs, les codes obligatoires, les calculs de totaux, la logique de taxe, les identifiants des parties, etc.
Pass = la facture est acceptable pour tout système comptes fournisseurs conforme EN 16931 dans l’UE. Fail = l’automatisation comptes fournisseurs du client rejettera la facture à réception, et l’équipe comptes clients devra traiter une exception manuelle.
Les cinq échecs les plus fréquents
Ils reviennent souvent côté Mustang dans validator quand les équipes testent leurs premières factures électroniques.
1. AFRelationship incorrect
ERROR: Embedded file factur-x.xml uses AFRelationship="Source",
expected "Alternative".
La spécification PDF autorise plusieurs types de relation pour les fichiers joints. Factur-X / ZUGFeRD exigent précisément Alternative : le XML joint est une représentation alternative du contenu visible du PDF. Si votre générateur PDF utilise Data (valeur par défaut de nombreuses bibliothèques), Mustang échoue immédiatement. Le PDF visible s’affiche toujours correctement, mais les données structurées restent invisibles pour le système fournisseurs.
2. Namespace XMP incorrect ou absent
ERROR: XMP metadata missing fx:DocumentType or fx:DocumentFileName under
namespace urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#.
Le paquet XMP du PDF doit déclarer le profil Factur-X (MINIMUM, BASIC, EN 16931, EXTENDED) et le nom de fichier à rechercher. C’est facile à oublier quand on écrit l’enveloppe PDF/A-3 à la main ; le point de terminaison /api/v1/e-invoice/render de gPdf émet ces champs automatiquement.
3. XML CII bien formé, mais EN 16931 Schematron échoue
ERROR: BR-CO-25 — In an invoice (BR-01) the
ram:SpecifiedTradePaymentTerms/ram:DueDateDateTime is required when
ram:DocumentTypeCode is 380.
C’est la majorité des échecs réels. Le XML est syntaxiquement valide ; les règles métier échouent. Les règles EN 16931 Schematron ont des IDs stables (BR-01, BR-CO-25, etc.) que vous pouvez retrouver dans la spécification. Les fréquentes :
- BR-01 : la facture doit avoir un numéro unique.
- BR-04 : la facture doit avoir une date d’émission.
- BR-05 : la facture doit avoir un code de type de facture.
- BR-CO-25 : les conditions de paiement sont requises quand le type de document est « Commercial invoice ».
- BR-Z-01 : le code de catégorie de taxe doit être l’un de
S,Z,E,AE,K,G,O,L,M.
Corrigez les données source, reconstruisez, puis revalidez.
4. Le wrapper PDF/A ne valide pas
INFO: CII XML extracted and validates against EN 16931.
ERROR: PDF/A-3b conformance check failed: missing Output Intent.
Ici, le contrôle XML de Mustang passe, mais l’enveloppe PDF/A-3 sous-jacente échoue. Cause fréquente : quelqu’un a écrit le XML correctement, mais a émis un PDF ordinaire au lieu d’un PDF/A-3. Le fichier embarqué existe, mais les règles de l’enveloppe d’archivage ne sont pas satisfaites. Le validateur de gpdf.com/validator/ le détecte en lançant veraPDF en parallèle : l’échec PDF/A-3 apparaît dans la colonne veraPDF tandis que Mustang indique que le XML passe.
5. Décalage entre encodage et déclaration
ERROR: XML declares <?xml version="1.0" encoding="UTF-8"?> but the
embedded byte stream is UTF-8 with BOM. Mustang strict mode rejects BOM.
Problème étonnamment courant lorsqu’un outil XML émet un BOM UTF-8 puis que le flux d’octets est embarqué tel quel. La correction : supprimer le BOM avant l’embarquement. Le point de terminaison e-invoice de gPdf normalise ce point.
Exécuter Mustang sans installer Java
Installer Java + la CLI Mustang convient pour un contrôle ponctuel. Pour une vérification continue — chaque facture générée, chaque exécution CI qui affirme la conformité de la facture électronique — c’est une friction inutile.
gpdf.com/validator/ exécute Mustang dans le navigateur :
- Déposez le PDF Factur-X / ZUGFeRD dans la zone de téléversement.
- Le validateur extrait le XML embarqué et exécute le moteur Schematron de Mustang (compilé en JavaScript / WebAssembly, exécuté dans un Cloudflare Worker).
- Le rapport Mustang revient à côté du rapport PDF/A-3 de veraPDF, puisque les deux couches doivent passer.
- Téléchargez le rapport JSON comme preuve QA.
Pas de connexion. Pas de quota. Le même type de Mustang que vous installeriez via Maven, servi comme service public gratuit.
TL;DR
Mustang signale 5 modes d’échec fréquents ; la plupart reviennent à « le fichier a été généré par un outil qui n’émet pas un PDF/A-3 Factur-X / ZUGFeRD pleinement conforme ». L’E-invoice API de gPdf l’émet en un seul appel. validator vérifie le résultat avec Mustang + veraPDF en parallèle.
La plupart des bugs que Mustang attrape concernent l’enveloppe ou AFRelationship, pas seulement la sémantique XML. Générer correctement le fichier est déjà l’essentiel ; le validateur est le reçu qui le prouve.