Docs › DORA

DORA Register of Information Lint

24 checks on the register CSV before it reaches the supervisor โ€” LEI check digits, ISO dates and codes, references that resolve

Who it is for. Compliance and data engineers at EU banks, insurers, investment firms and payment institutions who produce the DORA Register of Information export (Regulation (EU) 2022/2554, Article 28(3))

What it checks (24 rules: 16 error, 8 warn)

RuleLevelWhat it flagsMessage
missing_columnerrorRequired column absentThe header has no column for "{label}". Every row is therefore unchecked for it.
delimiter_not_commawarnSemicolon-separated fileThis file is semicolon-separated (a regional Excel export). Parsed with ';' - re-export as comma-separated UTF-8 before you upload it.
mojibakewarnBroken UTF-8"{value}" looks like UTF-8 read as Latin-1. Provider names with accents will reach the supervisor mangled.
row_field_counterrorRow width differs from headerThis row has {got} fields, the header has {want}. An unescaped comma or quote has shifted every value after it.
empty_requirederrorRequired cell empty"{label}" is empty on this row.
lei_lengtherrorLEI is not 20 characters"{label}" is "{value}" - {got} characters. An LEI (ISO 17442) is exactly 20.
lei_charseterrorLEI has illegal characters"{label}" is "{value}" - an LEI is upper-case A-Z and 0-9 only.
lei_checksumerrorLEI check digits fail"{label}" is "{value}" - the last two digits should be {want}, not {got} (ISO 7064 MOD 97-10). One character is wrong or transposed.
lei_placeholdererrorLEI is a placeholder"{label}" is "{value}" - a placeholder, not an identifier.
lei_name_conflictwarnOne LEI, two namesLEI {value} is filed as "{got}" here and "{want}" on line {other}. The supervisor keys on the LEI; pick one legal name.
duplicate_contract_referrorContract reference used twiceContractual arrangement reference "{value}" is already used on line {other}. References must be unique across the register.
duplicate_rowwarnIdentical rowThis row repeats line {other} field for field.
unresolved_linkerrorLinked arrangement not in the fileThis row points at overarching arrangement "{value}", which no row in this file declares. The link will not resolve.
self_linkwarnRow links to itselfThis row names itself ("{value}") as its own overarching arrangement.
date_formaterrorDate is not ISO 8601"{label}" is "{value}". Write dates as yyyy-mm-dd - {got} is read the other way round outside your locale.
date_impossibleerrorDate does not exist"{label}" is "{value}" - there is no such day in the calendar.
date_ordererrorContract ends before it startsEnd date {got} is earlier than start date {want}.
contract_expiredwarnArrangement already endedThis arrangement ended on {value}, before the reference date {want}. A terminated contract still listed as live is a finding the reviewer raises, not you.
country_shapeerrorCountry is not a 2-letter code"{label}" is "{value}". This field takes an ISO 3166-1 alpha-2 code (two upper-case letters), not a country name.
country_unknownwarnUnrecognised country code"{value}" is not in this extension's ISO 3166-1 alpha-2 list. Check it before you file.
currency_shapeerrorCurrency is not a 3-letter code"{label}" is "{value}". This field takes an ISO 4217 alpha-3 code, not a symbol or a name.
currency_unknownwarnUnrecognised currency code"{value}" is not in this extension's ISO 4217 list. Check it before you file.
bool_tokenerrorYes/no field is neither"{label}" is "{value}". This field is yes or no - a free-text answer cannot be aggregated.
amount_formaterrorAmount is not a plain number"{label}" is "{value}". Report the amount as digits with an optional decimal point ({want}) - thousands separators and symbols break the load.

Run it

ext install ReadyStack.dora-register-lint                       # VS Code ยท Cursor/VSCodium via Open VSX
npx -y @readystack/dora-register-lint register.csv        # CLI, free, every rule
npx -y @readystack/dora-register-lint --dir . --ci             # whole repository, exit 1 on errors (licence)
docker run --rm -v "$PWD:/w" getreadystack/dora-register-lint /w   # Docker

MCP (Claude Code, Cursor, Windsurf): check_text and check_file are free, check_dir needs a key.

{ "mcpServers": { "dora-register-lint": { "command": "npx", "args": ["-y", "@readystack/dora-register-lint", "--mcp"] } } }

Sample report

A deliberately wrong sample file, then the real output of npx @readystack/dora-register-lint register.csv on it. Nothing here is mocked.

Sample input (register.csv)

b_01.01.0010;b_01.01.0020;b_01.02.0010;b_01.02.0020;b_01.02.0030
529900T8BM49AURSDO55;LEI;Example Bank AG;2024-13-01;DE
5299009UKX2XSNNVNW6;LEI;Example Bank Cloud GmbH;;DE

Output

/tmp/s152_flag/samples/register.csv
      1  warn  This file is semicolon-separated (a regional Excel export). Parsed with ';' - re-export as comma-separated UTF-8 before you upload it.
      1  error The header has no column for "LEI of the financial entity". Every row is therefore unchecked for it.
      1  error The header has no column for "LEI of the ICT third-party provider". Every row is therefore unchecked for it.
      1  error The header has no column for "Name of the ICT third-party provider". Every row is therefore unchecked for it.
      1  error The header has no column for "Contractual arrangement reference". Every row is therefore unchecked for it.
      1  error The header has no column for "Function identifier". Every row is therefore unchecked for it.
      1  error The header has no column for "Type of ICT service". Every row is therefore unchecked for it.
      1  error The header has no column for "Supports a critical or important function". Every row is therefore unchecked for it.
      1  error The header has no column for "Start date of the contract". Every row is therefore unchecked for it.
      1  error The header has no column for "End date of the contract". Every row is therefore unchecked for it.
      1  error The header has no column for "Country of provision of the service". Every row is therefore unchecked for it.
      1  error The header has no column for "Annual expense or estimated cost". Every row is therefore unchecked for it.
      1  error The header has no column for "Currency of the amount reported". Every row is therefore unchecked for it.

Free and licence

FreeCheck the register CSV open in your editor - every row, all 24 checks, findings in the Problems panel and a written summary in the output channel, no key and no account
With a key ($29 once)Sweep every register CSV in the workspace and write one dated report file (doraRegister-report.md) you can attach to the audit trail

The full run is free for the first 7 days. 7-day refund on every key. Worth it because: One hour of the compliance analyst who would otherwise re-check the file by hand costs more than the licence; a manual pass over an 800-row register is 24 x 800 = 19,200 check-row comparisons.

Get the key, $29 once Team key, every linter, $149

What comes next

The same register data has to survive the supervisor's own validation rules and the annual resubmission - the next gate is a full pre-submission validation pack for the whole reporting bundle, not one file.

Questions

What does DORA Register of Information Lint actually do?

It reads the register CSV open in your editor and runs 24 checks on it: it recomputes the ISO 7064 check digits inside every LEI, rejects dates that are not ISO 8601 or do not exist, flags country and currency values that are not ISO codes, finds duplicate contract references, links pointing at rows that are absent, and arrangements that ended before your reference date.

Who is it for?

The engineer or compliance analyst inside an EU financial entity - a bank, insurer, investment firm, payment or e-money institution - who generates the Register of Information export under DORA Article 28(3) and has to hand it to a national competent authority without it bouncing back for data quality rework.

Why not just ask an AI assistant or use a free CSV validator?

The register names every provider holding your data and every function that stops without them, so pasting it into a hosted assistant exports your outsourcing map. A generic CSV validator checks shape, not ISO 7064 check digits, not whether a linked arrangement reference exists in the file, not whether a contract already ended. This runs locally and does all three.

What is free and what needs a licence?

Checking the file open in your editor is free forever, with no key, no account and no limit on rows or runs - all 24 checks on every row. The licence covers a different job: sweeping every register CSV in the workspace at once and writing one dated report file you can attach to the audit trail. That sweep runs free for seven days first.

What would this cost me otherwise?

A person doing it by hand compares 24 checks against every row: an 800-row register is 19,200 comparisons, and the LEI check digits cannot be done by eye at all. One hour of a financial-sector compliance analyst costs more than the 29 dollar licence, which is a one-off with a seven-day full refund and one key per person or CI seat.

A linter tells you what the rule says and where your file disagrees. It is not legal advice; the rule set carries its own date and is updated when the regulation moves.

Support · Pricing · Changelog

Install free

Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.

VS Code MarketplaceOpen VSX (Cursor, VSCodium)npmMCP server (npx)Docker Hub
ext install ReadyStack.dora-register-lint
npx @readystack/dora-register-lint <file>
npx @readystack/dora-register-lint --mcp

Team? One key for every ReadyStack linter, 5 seats, $149 once