After downloading Mustang, besides integrating into your software you can also use it on the command line:

Extract XML

➜ target git:(master) ✗ java -jar Mustang-CLI-2.1.0.jar --action extract

Source PDF (default: invoice.pdf):
Ouput PDF (default: invoice.ZUGFeRD.pdf):
Written to invoice.ZUGFeRD.pdf

Combining PDF and XML

In this case the source PDF has to be a PDF/A-1 like our “blanko

java -jar Mustang-CLI-2.1.0.jar --action combine
Source PDF (default: invoice.pdf):
ZUGFeRD XML (default: ZUGFeRD-invoice.xml):
Ouput PDF (default: invoice.ZUGFeRD.pdf):
ZUGFeRD version (1 or 2) (default: 1):
ZUGFeRD profile b)asic, c)omfort or e)xtended (default: e):
Written to invoice.ZUGFeRD.pdf

Validate ZUGFeRD 1, 2 or XRechnung files

As an example the validation of a specified, valid XML file with the –no-notices option. To additionally omit non-XML-output redirect error out to /dev/null on Linux and Mac, to NUL on MS Windows cmd.exe and to $null on MS Windows Powershell:

java -jar Mustang-CLI-2.1.0.jar --no-notices --action validate --source=invoice.xml 2>/dev/null
<?xml version="1.0" encoding="UTF-8"?>

<validation filename="invoice.xml" datetime="2020-11-12 10:45:12">
      <validator version="2.0.0"/>
      <duration unit="ms">8225</duration>
    <summary status="valid"/>
  <summary status="valid"/>

Or as an example a invalid pdf file without –no-notices:

Source PDF or XML (default: invoice.pdf):
10:49:38.729 [main] ERROR o.m.validator.ZUGFeRDValidator - Error 25: Unsupported profile type
10:49:38.790 [main] INFO  c.h.s.x.SchematronResourceXSLTCache - Compiling XSLT instance [cpPath=/xslt/ZF_211/FACTUR-X_EN16931.xslt; urlResolved=true; URL=jar:file:/C:/Users/jstaerk/workspace/mustangproject/Mustang-CLI/target/Mustang-CLI-2.0.0.jar!/xslt/ZF_211/FACTUR-X_EN16931.xslt]
10:49:46.128 [main] INFO  c.h.s.x.SchematronResourceXSLTCache - Compiling XSLT instance [cpPath=/xslt/cii16931schematron/EN16931-CII-validation.xslt; urlResolved=true; URL=jar:file:/C:/Users/jstaerk/workspace/mustangproject/Mustang-CLI/target/Mustang-CLI-2.0.0.jar!/xslt/cii16931schematron/EN16931-CII-validation.xslt]
10:49:46.943 [main] INFO  c.h.s.x.SchematronResourceXSLTCache - Compiling XSLT instance [cpPath=/xslt/XR_20/XRechnung-CII-validation.xslt; urlResolved=true; URL=jar:file:/C:/Users/jstaerk/workspace/mustangproject/Mustang-CLI/target/Mustang-CLI-2.0.0.jar!/xslt/XR_20/XRechnung-CII-validation.xslt]
10:49:47.043 [main] INFO  o.m.validator.XMLValidator - FailedAssert
10:49:47.048 [main] INFO  o.m.validator.ZUGFeRDValidator - Notice 27: [BR-DE-15] Das Element "Buyer reference" (BT-10) muss ³bermittelt werden.
10:49:47.049 [main] INFO  o.m.validator.XMLValidator - FailedAssert
10:49:47.052 [main] INFO  o.m.validator.ZUGFeRDValidator - Notice 27: [BR-DE-21] Das Element "Specification identifier" (BT-24) soll syntaktisch der Kennung des Standards XRechnung entsprechen.
10:49:47.052 [main] INFO  o.m.validator.XMLValidator - FailedAssert
10:49:47.052 [main] INFO  o.m.validator.ZUGFeRDValidator - Notice 27: [BR-DE-2] Die Gruppe "SELLER CONTACT" (BG-6) muss ³bermittelt werden.
10:49:47.083 [main] INFO  o.m.validator.ZUGFeRDValidator - Parsed PDF:valid XML:invalid Signature:Mustang Checksum:392A91BA0FB8BF07BE93BE5A9629987E1F80EDBA Version:2 Took:11927ms Errors:[25,27,27,27]
<?xml version="1.0" encoding="UTF-8"?>

<validation filename="invoice.pdf" datetime="2020-11-12 10:49:35">
        <releaseDetails id="core" version="1.16.1" buildDate="2020-05-12T00:43:00+02:00"/>
        <releaseDetails id="validation-model" version="1.16.1" buildDate="2020-05-12T00:46:00+02:00"/>
          <item size="110821">
          <validationReport profileName="PDF/A-3U validation profile" statement="PDF file is compliant with Validation Profile requirements." isCompliant="true">
            <details passedRules="126" failedRules="0" passedChecks="11415" failedChecks="0"/>
          <duration start="1605174575761" finish="1605174578071">00:00:02.310</duration>
      <batchSummary totalJobs="1" failedToParse="0" encrypted="0">
        <validationReports compliant="1" nonCompliant="0" failedJobs="0">1</validationReports>
        <featureReports failedJobs="0">0</featureReports>
        <repairReports failedJobs="0">0</repairReports>
        <duration start="1605174575397" finish="1605174578105">00:00:02.708</duration>
      <duration unit="ms">3209</duration>
    <summary status="valid"/>
      <validator version="2.0.0"/>
      <duration unit="ms">8505</duration>
      <error type="25">Unsupported profile type</error>
      <notice type="27" location="/*:CrossIndustryInvoice[namespace-uri()='urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100'][1]" criterion="rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement/ram:BuyerReference[boolean(normalize-space(.))]">[BR-DE-15] Das Element "Buyer reference" (BT-10) muss übermittelt werden.</notice>
      <notice type="27" location="/*:CrossIndustryInvoice[namespace-uri()='urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100'][1]/*:ExchangedDocumentContext[namespace-uri()='urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100'][1]" criterion="ram:GuidelineSpecifiedDocumentContextParameter/ram:ID = ''">[BR-DE-21] Das Element "Specification identifier" (BT-24) soll syntaktisch der Kennung des Standards XRechnung entsprechen.</notice>
      <notice type="27" location="/*:CrossIndustryInvoice[namespace-uri()='urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100'][1]/*:SupplyChainTradeTransaction[namespace-uri()='urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100'][1]/*:ApplicableHeaderTradeAgreement[namespace-uri()='urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100'][1]/*:SellerTradeParty[namespace-uri()='urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100'][1]" criterion="ram:DefinedTradeContact">[BR-DE-2] Die Gruppe "SELLER CONTACT" (BG-6) muss übermittelt werden.</notice>
    <summary status="invalid"/>
  <summary status="invalid"/>

The input can be a PDF or a XML file. Factur-X/ZUGFeRD 1, 2.11 and XRechnung 2 are supported. Files in the EN16931 profile are additionally validated against XRechnung on an notice-level unless –no-notices is specified. The according notices are thrown as errors if it’s a “XRechnung” (reference profile) or a real XRechnung. In case of
PDF input the PDF is additionally validated using an embedded VeraPDF, the results are included in the XML report.
The result will be XML on standard output and potentially messages on error out, as well as a log in a “logs” directory. If you want to analyze this log in real time, there is a suitable config file for Elasticsearch/Logstash/Kibana .
The following error types are specified:

section meaning
1 file not found
2 additional data schema validation fails
3 xml data not found
4 schematron rule failed
5 file too small
6 VeraPDFException
7 IOException PDF
8 File does not look like PDF nor XML (contains neither %PDF nor <?xml)
9 IOException XML
11 XMP Metadata: ConformanceLevel not found
12 XMP Metadata: ConformanceLevel contains invalid value
13 XMP Metadata: DocumentType not found
14 XMP Metadata: DocumentType invalid
15 XMP Metadata: Version not found
16 XMP Metadata: Version contains invalid value
18 schema validation failed
19 XMP Metadata: DocumentFileName contains invalid value
20 not a pdf
21 XMP Metadata: DocumentFileName not found”)
22 generic XML validation exception
23 Not a PDF/A-3
24 Issues in CEN EN16931 Schematron Check
25 Unsupported profile type
26 No rules matched, XML to minimal?
27 XRechnung schematron validation

The return code of the commandline call will be 0 on correct and !=0 on invalid files.
Use –action validateExpectValid and –d to specify a directory whose contents are supposed to be valid, for directories with intentionally only invalid files use –action validateExpectInvalid for a return code of 0 on directories with invalid files.

Visualize XML


java -jar Mustang-CLI-2.1.0.jar --action visualize

you can convert UN/CEFACT XML to HTML, which is a experimental feature, in particular for the Extended profile of ZUGFeRD 2. Please report any issues which may arise with steps to reproduce.

Convert PDF/A-1 to PDF/A-3

java -jar Mustang-CLI-2.1.0.jar --action a3only

Migrates a PDF/A-1 into a PDF/A-3 file without adding ZUGFeRD metadata hinzuzufügen. The same contents will be labelled the new version (which is valid because the format is backward-compatible), additional features like the PDF/A-2 JPG2000-compression of images will not be used.

Migrating ZUGFeRD 1 to 2

java -jar Mustang-CLI-2.1.0.jar -- action upgrade
        source (default: ZUGFeRD-invoice.xml):
        ZUGFeRD 2.0 XML target (default: factur-x.xml):
    Written to factur-x.xml

To migrate XML from ZF1 to Version 2 Mustangproject internally uses a self written (read: incomplete) XSLT-Transformation. Corrections and amendments are much appreciated.


The original purpose for the command line tool was finding out, how many ZUGFeRD invoices already existed in a directory structure of PDFs.

java -jar Mustang-CLI-2.1.0.jar --action metrics -d <Directory name>


java -jar Mustang-CLI-2.1.0.jar --action metrics -d /tmp/XMLExamples
Files: 145 Dirs: 15 PDF: 18 ZUGFeRD: 14

Each dot is a checked file.
The software works recursively, in this example 18 PDF files were found in 15 directories. 14 of those 18 files were identified as ZUGFeRD 1 or 2.Usually only files ending in .pdf, .PDF etc. are checked. By additionally specifying -i it is possible to check independently from file name extension.

java -jar Mustang-CLI-2.1.0.jar -l

With -l it is possible to pass a list of files to be checked for ZUGFeRDIty via standard input. A empty last line starts the check.

java -jar Mustang-CLI-2.1.0.jar -l
Files: 19 Dirs: 0 PDF: 19 ZUGFeRD: 15

Verbose parameters

If you want to use mustang non-interactively, e.g. in a script, you may, depending on the operation, use the following parameters to specify details:

–source <filename>
set input PDF file
–source-xml <filename>
set input XML file
–out <filename>
set output PDF file
–format <fx|zf>
enable factur-x or ZUGFeRD
–version <1|2>
set ZUGFeRD version
–profile <…>
set ZUGFeRD profile

  • For ZUGFeRD v1: <b>ASIC, <c>OMFORT or <e>XTENDED
  • For ZUGFeRD v2: <m>INIMUM, BASIC <w>L, <b>ASIC, <c>IUS, <e>N16931, E<x>TENDED