2026 年にドイツの B2B 顧客へ電子インボイスを送るなら、そのファイルは ZUGFeRD 準拠として通るか、受領時に差し戻されるかのどちらかです。フランスの Factur-X でも同じです。形式は、PDF/A-3 の枠組みに EN 16931 CII XML を添付したものです。ゼロから生成するのは簡単ではなく、検証には基準になるエンジンが必要です。
実務上、その基準になるエンジンが Mustang(mustangproject.org)です。PDF/A-3 から埋め込み XML を抽出し、EN 16931 Schematron に照らして検証するオープンソースの Java プロジェクトです。ZUGFeRD と Factur-X に対するオープンソースツールの中では最も深く対応しており、多くの独立検証者が実際に使っています。
この記事では、Mustang が指摘する失敗パターンと、それをより速く実行する方法を見ていきます。
Mustang が実際に確認すること
Factur-X または ZUGFeRD PDF を Mustang に渡すと、おおむね次を実行します。
- 埋め込みファイルを抽出する。PDF/A-3 は添付ファイルを
/EmbeddedFiles名前ツリーに保存します。Mustang は標準的なファイル名(Factur-X ならfactur-x.xml、ZUGFeRD 2.x ならzugferd-invoice.xml)を探し、バイト列を取り出します。 - AFRelationship を確認する。添付ファイルは、Factur-X / ZUGFeRD の基準に従って
AFRelationship="Alternative"と宣言されている必要があります。それ以外(Source、Data、Supplement)は失敗します。 - XMP 名前空間とバージョンを確認する。Factur-X 1.0 は
urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#を使います。ZUGFeRD 2.x はurn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#を使います。名前空間またはバージョン文字列が間違っていれば失敗します。 - XML を Cross-Industry Invoice (CII) として解析する。XML は整形式で、正しい CII ルート要素(
rsm:CrossIndustryInvoice)から始まる必要があります。 - EN 16931 Schematron を実行する。ここが検証の大部分です。フィールドの意味、必須コード、合計金額の計算、VAT ロジック、取引当事者識別子など、約 200 の業務ルールを確認します。
Pass = EU 全域の EN 16931 準拠の買掛金処理システム(AP system)に受け入れられる請求書です。Fail = 顧客側の買掛金自動処理が受領時に請求書を拒否し、売掛金管理チーム(AR team)が手動例外として処理することになります。
よく見る 5 つの失敗パターン
チームが最初の電子インボイスをテストするとき、validator の Mustang 側で繰り返し出るものです。
1. Wrong AFRelationship
ERROR: Embedded file factur-x.xml uses AFRelationship="Source",
expected "Alternative".
PDF 仕様は、添付ファイルに複数の関係種別を許可しています。Factur-X / ZUGFeRD は特に Alternative を要求します。つまり、添付 XML は、表示上の PDF コンテンツの別表現です。PDF生成ツールが Data を使う設定になっていると、多くのライブラリではこれがデフォルトですが、Mustang はすぐに失敗します。表示上の PDF は正しく見えても、構造化された請求書データは AP system にとって有効ではありません。
2. Wrong / missing XMP namespace
ERROR: XMP metadata missing fx:DocumentType or fx:DocumentFileName under
namespace urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#.
PDF の XMP パケットは、この Factur-X プロファイル(例: MINIMUM、BASIC、EN 16931、EXTENDED)と、探すべきファイル名を宣言する必要があります。PDF/A-3 の枠組みを手で書くと抜けやすい箇所です。gPdf の /api/v1/e-invoice/render エンドポイントは、これらを自動で出力します。
3. CII XML は well-formed だが EN 16931 Schematron が失敗する
ERROR: BR-CO-25 — In an invoice (BR-01) the
ram:SpecifiedTradePaymentTerms/ram:DueDateDateTime is required when
ram:DocumentTypeCode is 380.
実運用の失敗の大半はここです。XML の構文は有効ですが、業務ルール が失敗しています。EN 16931 Schematron ルールには BR-01、BR-CO-25 などの安定した ID があり、EN 16931 仕様で調べられます。よくあるものは次です。
- BR-01: 請求書には一意の請求書番号が必要。
- BR-04: 請求書には発行日が必要。
- BR-05: 請求書には請求書種別コードが必要。
- BR-CO-25: 文書種別が “Commercial invoice” の場合、支払条件が必要。
- BR-Z-01: VAT 区分コードは
S、Z、E、AE、K、G、O、L、Mのいずれかでなければならない。
元データを修正し、再生成し、再検証します。
4. PDF/A の枠組み自体が検証に通らない
INFO: CII XML extracted and validates against EN 16931.
ERROR: PDF/A-3b conformance check failed: missing Output Intent.
これは、Mustang の XML チェックは通るが、土台になっている PDF/A-3 の枠組みが失敗しているケースです。よくある原因は、XML は正しく書いたものの、PDF/A-3 ではなく通常の PDF を出力していることです。埋め込みファイルは存在しますが、アーカイブ用の枠組みに求められるルールを満たしていません。gpdf.com/validator/ は veraPDF を並列に実行するため、PDF/A-3 の失敗は veraPDF 側の列に表示され、Mustang は XML pass と報告します。
5. Encoding / declaration mismatch
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.
XML を生成するツールが UTF-8 BOM を出力し、それをそのまま埋め込むと、意外なほどよく起きます。修正は、埋め込み前に BOM を取り除くことです(gPdf の e-invoice エンドポイントはこれを正規化します)。
Java をインストールせずに Mustang を実行する
単発チェックなら、Java + Mustang CLI を入れても構いません。しかし継続的な検証、つまり請求書を生成するたび、または電子インボイス準拠を CI で確認するたびに実行するなら、その手間は不要です。
gpdf.com/validator/ は Mustang を ブラウザ内で実行します。
- Factur-X / ZUGFeRD PDF をアップロードゾーンへドラッグする。
- 検証ツールが埋め込み XML を抽出し、Mustang の Schematron エンジンを実行する(JavaScript / WebAssembly にコンパイルされ、Cloudflare Worker で動く)。
- Mustang のレポートが veraPDF の PDF/A-3 レポートと横並びで返る(両方のレイヤーが通る必要があるため)。
- QA 証跡として JSON レポートをダウンロードする。
ログインなし。クォータなし。Maven 経由でインストールするのと同じ Mustang を、無料の公開サービスとして使えます。
TL;DR
Mustang は 5 つの典型的な失敗パターンを指摘します。その多くは、「完全準拠の Factur-X / ZUGFeRD PDF/A-3 を出力しないツールで生成された」ことに集約されます。gPdf の E-invoice API は、それを 1 回の呼び出しで出力します。validator は、Mustang + veraPDF の 2 エンジンで結果を並列検証します。
Mustang が捕まえるバグの多くは、XML の意味だけではなく、PDF/A-3 の枠組みや AFRelationship の問題です。ファイルを正しく生成することが勝負の大半で、この検証ツールはそれを証明する検証証跡です。