ESEF report packaging: a step-by-step example with iXBRL.
The first time someone hands you a 200-page CSRD report and asks "is this in the right format to file" the honest answer is usually "not quite yet." ESEF is the European Single Electronic Format, and a valid ESEF report package is a zipped bundle of HTML, XML, and metadata with a strict directory structure and a long list of validation rules. Most first-time filers fail validation on the same four mistakes. This post walks through the structure, the rules, and a minimum-viable example.
This one is for the person who is going to look at a validator error message at 22:00 the night before filing.
01What ESEF and iXBRL are, briefly
ESEF is the EU rule that all annual financial reports from issuers on EU regulated markets must be published as Inline XBRL (iXBRL). iXBRL is a single document that is simultaneously valid XHTML (human-readable) and valid XBRL (machine-readable), with XBRL facts embedded as XML tags inside the HTML. A browser renders the report. A machine parses the same file for tagged numbers and dimensions.
For CSRD, the same packaging approach is used: the management report's sustainability section is tagged using the ESRS XBRL taxonomy, and the whole thing ships inside an ESEF report package, validated against ESMA's reporting manual.
02The package structure
An ESEF report package is a zip file with a defined directory layout. Here is the minimum-viable shape:
├── META-INF/
│ ├── reportPackage.json
│ └── catalog.xml
└── reports/
├── primary-statements.xhtml // the iXBRL document
└── taxonomy/
├── extension-tax.xsd // issuer extension taxonomy
├── extension-presentation.xml
├── extension-calculation.xml
├── extension-definition.xml
└── extension-labels.xml
The zip extension is .zip, not .esef or anything bespoke. The root inside the archive contains exactly two siblings: the META-INF/ folder and the reports/ folder. Nothing else.
META-INF/reportPackage.json
This is the package descriptor. It tells validators what is inside and what taxonomy version it claims to use. A minimum valid example:
{
"documentInfo": {
"documentType": "https://xbrl.org/report-package/2023",
"extends": [
"http://www.efrag.org/taxonomy/esrs/2023-12-22/esrs_all.xsd"
]
},
"reports": {
"default": {
"reportType": "inline-xbrl",
"documents": [ "reports/primary-statements.xhtml" ],
"taxonomy": [ "reports/taxonomy/extension-tax.xsd" ]
}
}
}
Two things matter here. The extends array points to the canonical ESRS taxonomy version. As of 2026 the only live release is 2023-12-22. The taxonomy array lists the entry point of your issuer-extension taxonomy, which we will get to below.
META-INF/catalog.xml
The catalog tells the validator how to resolve external schema references inside the package, mapping URIs to local file paths. A minimum valid catalog:
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<rewriteURI
uriStartString="http://www.efrag.org/taxonomy/esrs/"
rewritePrefix="../reports/taxonomy/"/>
</catalog>
Catalog mistakes are the single most common cause of "taxonomy not found" errors in third-party validators. If your validator says it cannot find the ESRS taxonomy and you know the file is there, the catalog mapping is almost always the bug.
03The iXBRL document
The XHTML file is where the actual reporting lives. It is valid XHTML so a browser renders it, with XBRL facts embedded as <ix:nonFraction> and <ix:nonNumeric> tags that browsers ignore and XBRL processors parse. A small example fragment:
<p>
Scope 2 emissions for the period were
<ix:nonFraction
name="esrs:GrossLocationBasedScope2GHGEmissions"
contextRef="period_2027"
unitRef="tCO2e"
decimals="0">1,118</ix:nonFraction>
tCO<sub>2</sub>e.
</p>
Five things make this fragment valid:
nameis a fully-qualified ESRS concept from the 2023-12-22 taxonomy. Concept names are case-sensitive and dimensional concepts have very specific spellings.contextRefpoints to a<xbrli:context>element declared elsewhere in the document, with the entity identifier, reporting period, and any dimensions (e.g. greenhouse gas, scope axis).unitRefpoints to a<xbrli:unit>declaration. ESRS uses ISO 4217 currency codes and a defined set of physical units like tCO2e, MWh, m3.decimalsis the precision claimed by the issuer. ESMA's rules require this to be present and accurate.- The displayed text
1,118matches what a numeric reader would parse out of the tag. Mismatch between displayed and tagged value is a validation error and an audit finding.
04The issuer extension taxonomy
Most issuers need to extend the base ESRS taxonomy with company-specific concepts: a subsidiary's identifier, an entity-specific emission factor, a domain member for a reporting segment. The extension taxonomy is a small XSD plus a handful of linkbases.
A minimum extension taxonomy XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ext="http://attera.example/2027/extension"
targetNamespace="http://attera.example/2027/extension"
xmlns:link="http://www.xbrl.org/2003/linkbase"
xmlns:xbrli="http://www.xbrl.org/2003/instance"
xmlns:xlink="http://www.w3.org/1999/xlink">
<xsd:import namespace="http://www.efrag.org/taxonomy/esrs/2023-12-22"
schemaLocation="../taxonomy/esrs_all.xsd"/>
<xsd:element id="ext_SubsidiaryName"
name="SubsidiaryName"
type="xbrli:stringItemType"
substitutionGroup="xbrli:item"
xbrli:periodType="duration"
nillable="true"/>
<link:linkbaseRef
xlink:type="simple"
xlink:href="extension-labels.xml"
xlink:arcrole="http://www.w3.org/1999/xlink/properties/linkbase"/>
</xsd:schema>
The extension must import the base taxonomy. Every extension concept must be anchored, via the definition linkbase, to a "wider" base-taxonomy concept that it is a more specific case of. Anchoring is mandatory under ESMA's rules; un-anchored extensions are a validation error.
05Four mistakes that fail validation
The recurring four:
1. Wrong taxonomy version
The 2023-12-22 ESRS taxonomy is the live version through 2026. Earlier drafts and public consultation versions are not valid for filings. Check the namespace and the URI in reportPackage.json.
2. Concept name typos
ESRS concept names are long and case-sensitive. GrossLocationBasedScope2GHGEmissions is correct. GrossLocationBasedScope2GhgEmissions is not. GrossLocationBasedScope2GreenhouseGasEmissions is not. Validators are unforgiving. Always copy concept names from the official taxonomy export rather than typing them.
3. Anchoring missing
Every extension concept must declare in the definition linkbase that it is a "wider-narrower" specialisation of an existing base-taxonomy concept. If you add ext:SubsidiaryAEmissions without anchoring it under esrs:GrossLocationBasedScope2GHGEmissions, the validator rejects it. This is an ESMA-specific rule, not an XBRL rule, so a generic XBRL processor may pass it through silently. Use an ESMA-aware validator.
4. Displayed and tagged values do not match
If the rendered text says 1.118,00 tCO₂e (European number format) and the iXBRL tag carries the value 1118, that is consistent. If the rendered text says 1,118 tCO₂e and the tag carries the value 1.118, that is a mismatch and a validation error. Use a single source of truth in the rendering pipeline. We learned this the hard way on a localisation pass that auto-translated punctuation but not the underlying numeric values.
06Validation
Two validators are worth using before filing:
- Arelle (open source). Run
arelle --plugins esef --file my-2027-report.zip. Free, command-line, picks up most ESMA rules with the ESEF plugin enabled. - ESMA's own filing rule checker, published as part of the reporting manual. Slower, but matches what the National Competent Authority will run on submission.
A clean Arelle run is necessary but not sufficient. The NCA-side validation occasionally catches issues Arelle's ESEF plugin tolerates, particularly around hash references, catalog mappings, and zip-level rules (no nested zips, no symlinks, no resource forks from a macOS zip tool).
07What Attera ships today
Attera's CSRD pipeline produces an iXBRL preview and an ESEF report package. The preview is structurally correct and passes Arelle's iXBRL conformance checks. The issuer extension taxonomy layer is on the roadmap and not shipped: today's output uses base-taxonomy concepts only, which means it is filing-ready for filings that do not require entity-specific extensions, and a stepping stone for filings that do.
We are honest about this distinction on the pricing page: today's output is "demo-grade iXBRL," not "filing-grade iXBRL." When the issuer extension layer lands later in 2026, the same packaging pipeline produces a fully ESMA-compliant report package without changing the input flow.
If you're preparing a first ESEF filing and want a 30-minute call to look at your draft package together, book the slot. Bring the zip. We'll run Arelle against it on the call and walk through the errors.
08Further reading
- ESMA ESEF Reporting Manual, current version.
- XBRL International, Inline XBRL 1.1 specification.
- XBRL Taxonomy Packages 1.0.
- Arelle open-source XBRL processor.
- EFRAG ESRS taxonomy, current version 2023-12-22.
This post is technical guidance for engineers building or reviewing ESEF report packages. Confirm filing requirements with a qualified auditor or external counsel before submission.