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
What it checks (24 rules: 16 error, 8 warn)
| Rule | Level | What it flags | Message |
|---|---|---|---|
missing_column | error | Required column absent | The header has no column for "{label}". Every row is therefore unchecked for it. |
delimiter_not_comma | warn | Semicolon-separated file | This file is semicolon-separated (a regional Excel export). Parsed with ';' - re-export as comma-separated UTF-8 before you upload it. |
mojibake | warn | Broken UTF-8 | "{value}" looks like UTF-8 read as Latin-1. Provider names with accents will reach the supervisor mangled. |
row_field_count | error | Row width differs from header | This row has {got} fields, the header has {want}. An unescaped comma or quote has shifted every value after it. |
empty_required | error | Required cell empty | "{label}" is empty on this row. |
lei_length | error | LEI is not 20 characters | "{label}" is "{value}" - {got} characters. An LEI (ISO 17442) is exactly 20. |
lei_charset | error | LEI has illegal characters | "{label}" is "{value}" - an LEI is upper-case A-Z and 0-9 only. |
lei_checksum | error | LEI 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_placeholder | error | LEI is a placeholder | "{label}" is "{value}" - a placeholder, not an identifier. |
lei_name_conflict | warn | One LEI, two names | LEI {value} is filed as "{got}" here and "{want}" on line {other}. The supervisor keys on the LEI; pick one legal name. |
duplicate_contract_ref | error | Contract reference used twice | Contractual arrangement reference "{value}" is already used on line {other}. References must be unique across the register. |
duplicate_row | warn | Identical row | This row repeats line {other} field for field. |
unresolved_link | error | Linked arrangement not in the file | This row points at overarching arrangement "{value}", which no row in this file declares. The link will not resolve. |
self_link | warn | Row links to itself | This row names itself ("{value}") as its own overarching arrangement. |
date_format | error | Date is not ISO 8601 | "{label}" is "{value}". Write dates as yyyy-mm-dd - {got} is read the other way round outside your locale. |
date_impossible | error | Date does not exist | "{label}" is "{value}" - there is no such day in the calendar. |
date_order | error | Contract ends before it starts | End date {got} is earlier than start date {want}. |
contract_expired | warn | Arrangement already ended | This 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_shape | error | Country 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_unknown | warn | Unrecognised country code | "{value}" is not in this extension's ISO 3166-1 alpha-2 list. Check it before you file. |
currency_shape | error | Currency 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_unknown | warn | Unrecognised currency code | "{value}" is not in this extension's ISO 4217 list. Check it before you file. |
bool_token | error | Yes/no field is neither | "{label}" is "{value}". This field is yes or no - a free-text answer cannot be aggregated. |
amount_format | error | Amount 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
| Free | Check 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.
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 Hubext 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