Guides · Updated 2026-10-20
pain.001 XSD validation errors and how to fix them
An XSD validation error means the file does not match the ISO 20022 schema of its pain.001 version. Java validators name the failed constraint with a W3C XML Schema code such as cvc-complex-type.2.4.a (an element that is not expected here) or cvc-pattern-valid (a value in the wrong format); libxml2-based tools such as xmllint describe the same problem in a sentence. Almost every error traces back to one element the export writes in the wrong place, with the wrong value or for the wrong version.
Error codes and what they mean
The cvc-… codes name the validation rule of the W3C XML Schema 1.0 specification that failed. The libxml2 wording below is what xmllint and lxml print (namespaces shortened to {ns}); BankLint uses libxml2 and reports each error as one of the rules in the last column.
| Code (Java/Xerces) | libxml2 wording | Meaning | BankLint rule |
|---|---|---|---|
cvc-complex-type.2.4.a | "This element is not expected. Expected is ( … )." | An element is misplaced, misspelt, from another version, or an element before it is missing. | BNK-ISO-001 |
cvc-complex-type.2.4.b | "Missing child element(s). Expected is ( … )." | The element ends before a mandatory child. | BNK-ISO-001 or BNK-ISO-002 |
cvc-complex-type.2.3 | "Character content other than whitespace is not allowed because the content type is 'element-only'." | Text where only child elements are allowed. | BNK-ISO-099 |
cvc-pattern-valid | "[facet 'pattern'] The value '…' is not accepted by the pattern '…'." | The value does not match the format, for example an IBAN, BIC or currency code. | BNK-ISO-003 |
cvc-maxLength-valid, cvc-minLength-valid | "[facet 'maxLength'] The value has a length of '36'; this exceeds the allowed maximum length of '35'." | The text is too long, or empty. | BNK-ISO-004 |
cvc-enumeration-valid | "[facet 'enumeration'] The value '…' is not an element of the set { … }." | The code is not in the schema’s code list. | BNK-ISO-005 |
cvc-datatype-valid.1.2.1 | "'…' is not a valid value of the atomic type 'ISODate'." | Wrong date, date-time, decimal or boolean format. | BNK-ISO-006 |
cvc-fractionDigits-valid, cvc-totalDigits-valid | "[facet 'fractionDigits'] The value '…' has more fractional digits than are allowed ('5')." | Too many decimals or digits. | BNK-ISO-007 |
cvc-minInclusive-valid, cvc-maxInclusive-valid | "[facet 'minInclusive'] The value '…' is less than the minimum value allowed ('0')." | A number below or above the allowed range. | BNK-ISO-008 |
cvc-complex-type.3.2.2, cvc-complex-type.4 | "The attribute 'Ccy' is required but missing." | An attribute is not allowed, or a required one is missing. | BNK-ISO-009 |
cvc-elt.1 | "No matching global declaration available for the validation root." | The root element or its namespace does not belong to this schema. | BNK-ISO-010 |
Java validators often add cvc-type.3.1.3 ("the value of element … is not valid") after a format error on the same element; fixing the first error fixes both. A validator reports the first element that does not fit, which is often the element after a missing one.
Element in the wrong place or missing
Schema elements form a fixed sequence. In the group header MsgId must come first, so a file that omits it, or writes CreDtTm before it, fails on CreDtTm: libxml2 reports "Element 'CreDtTm': This element is not expected. Expected is ( MsgId )." Try the synthetic file without MsgId.
<GrpHdr>
<CreDtTm>2026-10-16T09:00:00</CreDtTm>
<MsgId>MSG-2026-0001</MsgId>
...<GrpHdr>
<MsgId>MSG-2026-0001</MsgId>
<CreDtTm>2026-10-16T09:00:00</CreDtTm>
...- BNK-ISO-001BLOCKERElement not expected at this position. The ISO 20022 schema does not allow this element here: an element is missing, misplaced or not permitted.
A pain.001.001.03 element in a .09 file
When an export is switched to the .09 namespace without changing the mapping, the old element names fail. In .09 the agent BIC is BICFI (it was BIC), and the requested execution date is a choice of Dt or DtTm (it was a plain date). libxml2 reports "Element 'BIC': This element is not expected. Expected is one of ( BICFI, ClrSysMmbId, LEI, Nm, PstlAdr, Othr )". All differences are listed in pain.001.001.03 vs pain.001.001.09.
<ReqdExctnDt>2026-10-20</ReqdExctnDt>
...
<DbtrAgt>
<FinInstnId>
<BIC>TESTDEFFXXX</BIC>
</FinInstnId>
</DbtrAgt><ReqdExctnDt>
<Dt>2026-10-20</Dt>
</ReqdExctnDt>
...
<DbtrAgt>
<FinInstnId>
<BICFI>TESTDEFFXXX</BICFI>
</FinInstnId>
</DbtrAgt>- BNK-ISO-001BLOCKERElement not expected at this position. The ISO 20022 schema does not allow this element here: an element is missing, misplaced or not permitted.
Wrong format: currency, IBAN, BIC
Pattern errors name the value and the pattern. Common cases: a currency code with more than three letters, an IBAN with spaces or a lowercase country code (the IBAN pattern is [A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}), and a BIC that is neither 8 nor 11 characters. Try the synthetic file with Ccy="EURO".
<InstdAmt Ccy="EURO">1250.00</InstdAmt>
<IBAN>DE15 2000 0000 0000 0000 11</IBAN><InstdAmt Ccy="EUR">1250.00</InstdAmt>
<IBAN>DE15200000000000000011</IBAN>- BNK-ISO-003BLOCKERValue does not match the required format. The value does not match the format pattern defined by the ISO 20022 schema.
Too long or empty
Identifiers such as MsgId, PmtInfId and EndToEndId allow at most 35 characters, and every text element needs at least one character. The SEPA guidelines also state that empty elements are not allowed. Leave an optional element out instead of writing it empty. Try the synthetic file with a 36-character MsgId.
<MsgId>MSG-2026-0001-PAYMENT-RUN-DAILY-1</MsgId>
<Nm></Nm><MsgId>MSG-2026-0001-RUN-1</MsgId>
<Nm>Example Supplier Alpha GmbH</Nm>- BNK-ISO-004BLOCKERValue too long / Value too short / Value length not allowed. The value is longer than the maximum length allowed by the ISO 20022 schema.
Code not in the list
Code elements accept only the values the schema lists: ChrgBr accepts DEBT, CRED, SHAR and SLEV, so a value like SHA fails the schema. Note that SHAR passes the schema but fails the SEPA rule, which allows only SLEV (charge bearer SLEV).
<ChrgBr>SHA</ChrgBr><ChrgBr>SLEV</ChrgBr>- BNK-ISO-005BLOCKERValue is not an allowed code. The value is not one of the codes allowed by the ISO 20022 schema.
- SEPA-SCT-CHRGBR-001BLOCKERCharge bearer must be SLEV. When the charge bearer is given for a SEPA credit transfer, only SLEV (following service level) is allowed.
Dates, times and decimals
Dates use YYYY-MM-DD, date-times YYYY-MM-DDThh:mm:ss, and amounts a decimal point without thousands separators. Local formats from the ERP fail as a data-type error.
<CreDtTm>2026-10-16 09:00:00</CreDtTm>
<Dt>20.10.2026</Dt>
<InstdAmt Ccy="EUR">1250,00</InstdAmt><CreDtTm>2026-10-16T09:00:00</CreDtTm>
<Dt>2026-10-20</Dt>
<InstdAmt Ccy="EUR">1250.00</InstdAmt>- BNK-ISO-006BLOCKERValue has the wrong data type. The value is not valid for the data type (for example date, decimal or boolean) required by the schema.
Decimals, negative amounts and attributes
The schema allows amounts with up to five decimals and no negative values; SEPA allows at most two decimals (SEPA-SCT-AMT-002). Every amount needs its Ccy attribute.
<InstdAmt Ccy="EUR">1250.000001</InstdAmt>
<InstdAmt Ccy="EUR">-1250.00</InstdAmt>
<InstdAmt>1250.00</InstdAmt><InstdAmt Ccy="EUR">1250.00</InstdAmt>- BNK-ISO-007BLOCKERToo many decimal places / Too many digits. The value has more fraction digits than the ISO 20022 schema allows.
- BNK-ISO-008BLOCKERValue below the allowed minimum / Value above the allowed maximum. The value is smaller than the minimum allowed by the ISO 20022 schema.
- BNK-ISO-009BLOCKERAttribute not allowed / Required attribute missing. The element carries an attribute that the ISO 20022 schema does not allow.
Questions
What does cvc-complex-type.2.4.a mean in a pain.001 file?
An element appears where the schema expects a different one: it is in the wrong order, misspelt, from another message version, or a mandatory element before it is missing. The message lists the element or elements the schema expected at that position.
Why does the error name an element that is correct?
The validator reports the first element that does not fit the expected sequence. When a mandatory element is missing, that is usually the element right after the gap.
Is a pain.001 file without XSD errors SEPA compliant?
Not necessarily. SEPA is a stricter subset of ISO 20022: for example SHAR is a valid charge bearer code in the schema but not in SEPA, and names may have 140 characters in the schema but 70 in SEPA.
Validate a pain.001 fileFree, no account needed, files are not stored.
More guides
- How to validate a pain.001 payment file
- pain.001.001.09 XML example for a SEPA credit transfer
- pain.001.001.03 vs pain.001.001.09: what changed and how to migrate
- Structured, hybrid and unstructured addresses in SEPA pain.001
- IBAN and BIC in a SEPA pain.001
- Remittance information in a SEPA pain.001 (Ustrd, Strd, RF)
- SEPA Credit Transfer rules for pain.001.001.09
- Why banks reject pain.001 files
- Payment-file regression testing after SAP or TMS changes
- Charge bearer SLEV in SEPA credit transfers
- Control sum (CtrlSum) and number of transactions (NbOfTxs) in pain.001
- SEPA character set, names and identifiers