The hard part of NIS2 incident reporting is not the pipeline that files the report. It is the decision, often taken at 3am by whoever is on call, about whether the thing in front of them is a “significant incident” at all — because that decision, and nothing else, starts the 24-hour clock.
Most NIS2 reporting projects I see are built back to front. Teams invest in the notification workflow — the CSIRT portal integration, the templated early warning, the escalation chat — and treat the classification as a footnote. It is the other way round. Article 23 of Directive (EU) 2022/2555 hangs every deadline off the moment the entity becomes aware of a significant incident. Get the significance call wrong and the best reporting pipeline in Europe fires late, or never, or floods the competent authority with noise. The engineering problem worth solving is the classifier, not the courier.
What the clock actually hangs on
Article 23 sets a staged cascade. Once an entity is aware of a significant incident it must submit an early warning without undue delay and in any event within 24 hours; a fuller incident notification within 72 hours, updating the severity, impact and any indicators of compromise; an intermediate report on request from the CSIRT or competent authority; and a final report within one month of the notification, covering root cause, mitigations and lessons learned. The early warning is deliberately thin — it flags whether the incident is suspected to be the result of unlawful or malicious acts and whether it could have cross-border impact — but it has to go out fast.
Every one of those deadlines runs from the same event: awareness of a significant incident. Not awareness of an incident. Not the moment the SOC opens a ticket. The trigger is a legal characterisation, and if your process leaves that characterisation to an unassisted human under pressure, you have built a stopwatch whose start button nobody can find in the dark.
Where “significant” is defined, and where it isn’t
The directive gives a qualitative test. Article 23(3) says an incident is significant if it has caused or is capable of causing severe operational disruption of the services or financial loss for the entity, or if it has affected or is capable of affecting other persons by causing considerable material or non-material damage. That is the whole of it for most in-scope sectors — energy, transport, health, water, and the rest. It is a standard, not a number, and it will be sharpened by each member state’s transposing law and its national authority’s guidance rather than by the directive itself.
For one band of entities there are actual numbers. Commission Implementing Regulation (EU) 2024/2690 sets horizontal significance thresholds for the digital infrastructure and digital service providers it covers — DNS providers, TLD registries, cloud and data-centre providers, content delivery networks, managed service and managed security service providers, online marketplaces, search engines, social-networking platforms and trust service providers. Those thresholds include a direct financial loss at or above €500,000 or 5% of annual turnover, whichever is lower; the successful exfiltration of trade secrets; death or serious damage to a person’s health; and successful unauthorised access capable of causing severe operational disruption. Recurrent incidents sharing the same apparent root cause within a six-month window can be aggregated and counted as one significant incident even where each on its own falls short.
So you are working with a mixed picture: hard numbers for a defined set of digital providers, and a qualitative standard for everyone else. The mistake is to treat the qualitative standard as unencodable. It is not. You can encode a defensible proxy — the digital-provider thresholds are a reasonable starting point for the money and safety limbs — and record the reasoning, which is exactly what a supervisor will ask to see. This is the same discipline behind turning the Article 21 measures into concrete controls: the obligation is abstract, the implementation cannot be.
Two failure modes, both expensive
An inconsistent significance decision fails in two directions. Decide too slowly or too conservatively and the clock starts late — you report at hour 40 for something the authority will say you were aware of at hour 2, and now you are explaining a missed 24-hour deadline as well as managing the incident. Decide too eagerly and you over-report: every degraded service and transient outage becomes an early warning, the competent authority learns to discount your filings, and your own responders spend the first hour of every event writing notifications instead of containing the incident. Credibility with a regulator is a depletable resource. Cry significant a dozen times and the one that matters lands in the same tray as the noise.
The way out is to make the significance test deterministic wherever the inputs allow, and to make the residual judgement explicit and logged where they don’t. Encode the thresholds. Feed them from the signals you already collect — loss estimates, affected-user counts, access-control alerts, safety events — and let the engine set the deadlines the moment it returns a positive.
Encoding the classification
A small rules engine does the heavy lifting. It takes the incident’s measured attributes, applies the thresholds, and returns both a verdict and the deadlines that verdict triggers — with the reasons attached, so the decision is auditable rather than a shrug.
from dataclasses import dataclass
from datetime import datetime, timedelta, timezone
# NIS2 significance classifier.
# Encodes the Article 23(3) test in Directive (EU) 2022/2555 together with the
# horizontal thresholds in Commission Implementing Regulation (EU) 2024/2690,
# which bind the digital-infrastructure entity types that regulation covers.
# The wider essential/important sectors work to the qualitative Article 23(3)
# standard; treat these thresholds as a defensible proxy, not a transposed rule.
# Verify every figure against your national transposing law before relying on it.
FINANCIAL_CAP_EUR = 500_000 # CIR 2024/2690: EUR 500 000 ...
TURNOVER_SHARE = 0.05 # ... or 5% of annual turnover, whichever is lower
@dataclass
class Incident:
aware_at: datetime # when the entity became aware, from detection
direct_loss_eur: float
annual_turnover_eur: float
unauthorised_access: bool # successful, capable of severe disruption
trade_secret_exfiltration: bool
death_or_serious_harm: bool
recurring_same_cause_6m: int # count of like incidents in the window
def classify(i: Incident) -> dict:
trigger = min(FINANCIAL_CAP_EUR, TURNOVER_SHARE * i.annual_turnover_eur)
reasons = []
if i.direct_loss_eur >= trigger:
reasons.append(f"direct financial loss at or above EUR {trigger:,.0f}")
if i.death_or_serious_harm:
reasons.append("death or serious damage to health")
if i.unauthorised_access:
reasons.append("unauthorised access risking severe disruption")
if i.trade_secret_exfiltration:
reasons.append("exfiltration of trade secrets")
if i.recurring_same_cause_6m >= 2:
reasons.append("recurrent incidents, same apparent cause, within six months")
significant = bool(reasons)
return {
"significant": significant,
"reasons": reasons,
# The reporting clock runs from awareness, not from this classification.
"early_warning_due": i.aware_at + timedelta(hours=24) if significant else None,
"notification_due": i.aware_at + timedelta(hours=72) if significant else None,
}
if __name__ == "__main__":
verdict = classify(Incident(
aware_at=datetime(2026, 9, 11, 14, 56, tzinfo=timezone.utc),
direct_loss_eur=180_000, # below the money threshold ...
annual_turnover_eur=9_000_000,
unauthorised_access=True, # ... but this limb still fires
trade_secret_exfiltration=False,
death_or_serious_harm=False,
recurring_same_cause_6m=0,
))
print(verdict)
The worked example matters more than the figures. A €180,000 loss sits well under the money threshold — 5% of a €9m turnover is €450,000 — yet the incident is significant anyway, because successful unauthorised access capable of severe disruption is an independent limb. That is precisely the judgement a tired responder gets wrong when they anchor on the loss figure and stop reading. The engine does not tire and does not anchor. What it must never do is decide silently: the verdict, the reasons and the two deadlines all belong in the incident record the moment they are computed.
Where the engine stops and a person starts
A classifier is a floor, not a ceiling. It should be tuned to fire readily — a false positive here costs a report, a false negative costs a breach — but it cannot capture “capable of causing” severe disruption for an event that has not yet manifested, and it will not know that this outage coincides with a coordinated campaign against your sector. So the design is: the engine escalates on a positive and cannot be silenced; a named human can escalate further on judgement but cannot downgrade the engine’s call without recording why. That asymmetry is the whole control. It keeps the clock honest while leaving room for the human to catch what the rules miss.
None of this lives in isolation. The same event may trip a CRA early-warning duty, a DORA major-incident notification, and a sector regulator’s own clock, each with its own definition of “significant” and its own window — which is why the classification layer has to feed a single view of overlapping duties rather than a NIS2 silo. If you have not mapped how these obligations stack, start with the board’s cyber-incident reporting map and the mechanics of building the 24-hour early-warning pipeline before you tune a single threshold.
NIS2 has been transposable since 17 October 2024 and enforcement is ramping unevenly across member states. When your first significant incident arrives, the authority will not ask to see your notification template. It will ask when you became aware, and why it took you until hour 40 to decide. Encode the answer now, before you have to improvise it.
Free interactive tool
Website compliance checklist
What your site has to do, based on what it actually does
Answer as much or as little as you like — the list builds as you go. Nothing is stored against your name and no email is required.
Everything that applies
Ordered by what to do first: legal requirements you can close quickly, then larger pieces of work, then what is expected rather than required. Not exhaustive, and not a legal audit.
Dated PDF, yours to keep or circulate.
Free interactive tool
Interactive deadline calculator
Check which regulations apply to you and when
Regulation across the EU, UK, US and Asia-Pacific has moved considerably in the past eighteen months, and several headline dates have shifted more than once. Twelve questions, about three minutes.
Results are shown on screen — no email required. A dated summary is available to download, and can be sent on if that's more useful. What we do with your answers.
Most technology problems are not technology problems. They are control problems.
The systems exist. The investment has been made. The question is whether leadership can understand, direct, evidence, and sustain what those systems produce. Find out where control exists — and where it only appears to.
Full Governance by Sixteen Pillars
Govern your business. Prove your compliance.
A board assurance cockpit for EU-regulated financial firms — tamper-evident, hash-chained proof of governance across DORA, GDPR, NIS2, ISO 27001, the EU AI Act and MiCA. In development.
See what's coming