ブログ

Mustang で ZUGFeRD を検証する:何が通り、何が落ちるのか

Mustang は Factur-X / ZUGFeRD の事実上の基準検証ツールです。PDF/A-3 に CII XML を埋め込むときの典型的な失敗パターンと、出荷前に検証する方法を整理します。

2026 年にドイツの B2B 顧客へ電子インボイスを送るなら、そのファイルは ZUGFeRD 準拠として通るか、受領時に差し戻されるかのどちらかです。フランスの Factur-X でも同じです。形式は、PDF/A-3 の枠組みに EN 16931 CII XML を添付したものです。ゼロから生成するのは簡単ではなく、検証には基準になるエンジンが必要です。

実務上、その基準になるエンジンが Mustangmustangproject.org)です。PDF/A-3 から埋め込み XML を抽出し、EN 16931 Schematron に照らして検証するオープンソースの Java プロジェクトです。ZUGFeRD と Factur-X に対するオープンソースツールの中では最も深く対応しており、多くの独立検証者が実際に使っています。

この記事では、Mustang が指摘する失敗パターンと、それをより速く実行する方法を見ていきます。

Mustang が実際に確認すること

Factur-X または ZUGFeRD PDF を Mustang に渡すと、おおむね次を実行します。

  1. 埋め込みファイルを抽出する。PDF/A-3 は添付ファイルを /EmbeddedFiles 名前ツリーに保存します。Mustang は標準的なファイル名(Factur-X なら factur-x.xml、ZUGFeRD 2.x なら zugferd-invoice.xml)を探し、バイト列を取り出します。
  2. AFRelationship を確認する。添付ファイルは、Factur-X / ZUGFeRD の基準に従って AFRelationship="Alternative" と宣言されている必要があります。それ以外(SourceDataSupplement)は失敗します。
  3. XMP 名前空間とバージョンを確認する。Factur-X 1.0 は urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0# を使います。ZUGFeRD 2.x は urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0# を使います。名前空間またはバージョン文字列が間違っていれば失敗します。
  4. XML を Cross-Industry Invoice (CII) として解析する。XML は整形式で、正しい CII ルート要素(rsm:CrossIndustryInvoice)から始まる必要があります。
  5. 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 プロファイル(例: MINIMUMBASICEN 16931EXTENDED)と、探すべきファイル名を宣言する必要があります。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-01BR-CO-25 などの安定した ID があり、EN 16931 仕様で調べられます。よくあるものは次です。

  • BR-01: 請求書には一意の請求書番号が必要。
  • BR-04: 請求書には発行日が必要。
  • BR-05: 請求書には請求書種別コードが必要。
  • BR-CO-25: 文書種別が “Commercial invoice” の場合、支払条件が必要。
  • BR-Z-01: VAT 区分コードは SZEAEKGOLM のいずれかでなければならない。

元データを修正し、再生成し、再検証します。

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 を ブラウザ内で実行します。

  1. Factur-X / ZUGFeRD PDF をアップロードゾーンへドラッグする。
  2. 検証ツールが埋め込み XML を抽出し、Mustang の Schematron エンジンを実行する(JavaScript / WebAssembly にコンパイルされ、Cloudflare Worker で動く)。
  3. Mustang のレポートが veraPDF の PDF/A-3 レポートと横並びで返る(両方のレイヤーが通る必要があるため)。
  4. 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 の問題です。ファイルを正しく生成することが勝負の大半で、この検証ツールはそれを証明する検証証跡です。