2026-04-20·13 min read·

NIS2 Art.39–40 Peer Reviews and EU-CyCLONe: How Cross-Border Crisis Coordination Changes Your Incident Response Obligations — Developer Guide 2026

NIS2 Articles 39 and 40 sit in Chapter VII alongside ENISA coordination and international cooperation. They tend to be skipped by developers focused on Art.21 security measures or the Art.23 incident reporting obligations. That is a mistake — especially for teams operating infrastructure, SaaS platforms, or open-source software used across multiple EU member states.

Article 39 creates a peer review mechanism for national competent authorities. Article 40 formalises EU-CyCLONe, the EU Cyber Crises Liaison Organisation Network. Together, they represent the EU's answer to the question: "What happens when a cybersecurity incident is too large for one member state to handle alone?"

The answer has direct consequences for how quickly you must report, who receives your reports, and what information you must disclose during a coordinated EU-level response.


1. What Art.39 Says: Peer Reviews of NCAs

Article 39 establishes a voluntary peer review system for member states' national competent authorities (NCAs). The review process works as follows:

Structure:

Scope of Review: The peer review mechanism evaluates:

Output: After a peer review, the reviewing team produces a report with findings and recommendations. The NCA under review is expected to develop an action plan addressing any identified gaps. Results feed into the NIS Cooperation Group (Art.14) for strategic oversight.

What Art.39 Does NOT Do

Art.39 peer reviews do not review regulated entities — your company, your infrastructure, your security practices. They review how the NCA manages its responsibilities. This distinction matters because developers sometimes confuse peer reviews with the supervisory inspections NCAs can conduct under Art.32.


2. Why Peer Reviews Matter for Developers (Indirect Effects)

Even though Art.39 reviews target NCAs rather than regulated entities, they create predictable second-order effects on enforcement behaviour that developers should understand.

Effect 1: Post-Review Enforcement Acceleration

NCAs that have undergone peer review frequently identify gaps in their enforcement consistency or technical capacity. In response to review recommendations, these NCAs often:

Developer implication: If your NCA has recently completed a peer review and received recommendations about light-touch enforcement, expect increased audit activity in the 12–18 months following the review.

Effect 2: NCA Benchmark Convergence

Before peer reviews, NCA enforcement standards varied significantly across member states. Germany's BSI operated differently from France's ANSSI, which operated differently from smaller member states' NCAs. Peer reviews create upward pressure toward the practices of high-performing NCAs.

This matters because:

Effect 3: Published Findings Create Precedent

Peer review findings are reported to the NIS Cooperation Group, which progressively publishes guidance based on common themes. This creates de facto industry standards that go beyond what NIS2 explicitly requires.


3. What Art.40 Says: EU-CyCLONe

Article 40 establishes the EU Cyber Crises Liaison Organisation Network (EU-CyCLONe), formalising what had previously existed as an informal CYCLONE network. EU-CyCLONe is the operational-level crisis coordination infrastructure for large-scale cybersecurity incidents affecting multiple EU member states.

Membership

EU-CyCLONe Members:
├── Designated national authorities (one per MS)
│   └── Authority responsible for management of large-scale
│       cybersecurity incidents and crises
├── European Commission (observer status)
└── ENISA (provides secretariat support)

Membership is not the NCA itself — it is the national authority designated specifically for crisis management. In many member states this overlaps with the NCA (e.g., BSI in Germany, ANSSI in France), but in others it may be a separate authority, typically a national cyber crisis centre or equivalent.

EU-CyCLONe Tasks (Art.40(2))

Article 40 assigns EU-CyCLONe six operational responsibilities:

TaskDescription
PreparednessIncrease preparedness for management of large-scale cybersecurity incidents and crises
Situational AwarenessDevelop and maintain shared situational awareness of large-scale incidents
Impact AssessmentAssess societal and economic consequences of large-scale cross-border incidents
Crisis CoordinationCoordinate management of large-scale incidents at operational level
Decision SupportPrepare decision-making support for the political level (EU Council, national governments)
Public CommunicationDevelop coordinated messaging to the public about large-scale incidents

Governance Position

EU-CyCLONe sits in the middle of a three-tier NIS2 governance hierarchy:

NIS2 Governance Hierarchy
─────────────────────────────────────────────────────
TIER 1 — STRATEGIC/POLICY
  NIS Cooperation Group (Art.14)
  ├── All MS representatives + EC + ENISA
  ├── Strategic guidance, policy coordination
  └── Receives CyCLONe annual reports

TIER 2 — OPERATIONAL/CRISIS  ← Art.40 EU-CyCLONe
  EU-CyCLONe (Art.40)
  ├── National cyber crisis authorities
  ├── Large-scale incident coordination
  └── Operational + decision-support

TIER 3 — TECHNICAL/INCIDENT
  CSIRT Network (Art.15)
  ├── National CSIRTs (one per MS)
  ├── Technical information sharing
  └── Incident response coordination

Support: ENISA (secretariat + technical support for all three)
─────────────────────────────────────────────────────

EU-CyCLONe reports to the NIS Cooperation Group annually and on request during crisis situations. The operating rules and working arrangements are adopted internally.


4. How EU-CyCLONe Activation Affects Your Art.23 Obligations

This is where Art.40 becomes directly operational for developers. EU-CyCLONe activation compresses incident response timelines and changes who receives your reports.

The Large-Scale Incident Escalation Path

When a cybersecurity incident exceeds national-level management capacity, it follows this escalation path:

Entity detects significant incident
           │
           ▼
Art.23: 24h Early Warning to NCA + CSIRT
           │
           ▼
CSIRT Network technical coordination begins
           │
           ▼ (if cross-border impact detected)
EU-CyCLONe activated for operational coordination
           │
           ▼
NCA may request additional entity-level data
(faster timeline, broader scope than standard Art.23)
           │
           ▼ (if societal/economic impact is significant)
NIS Cooperation Group + EC political-level engagement

Timeline Compression Under EU-CyCLONe

Under normal Art.23 reporting:

When EU-CyCLONe is activated and your incident is connected to the coordinated event:

Practical consequence: If your infrastructure is designated as essential (Art.3 essential entities) and an incident involving your services triggers EU-CyCLONe activation, expect your NCA to contact you for information on a timeline measured in hours, not days.

Cross-Border Information Sharing

EU-CyCLONe shares operational information among national crisis authorities. This means that incident details disclosed to your NCA during a EU-CyCLONe event may — subject to Art.38 confidentiality constraints — be shared with other national crisis authorities.

What this means in practice:

Art.38's professional secrecy obligation binds EU-CyCLONe members, so your disclosed information cannot be used for competitive or commercial purposes — but it does reach more hands than a standard Art.23 report.


5. What Triggers a "Large-Scale Cybersecurity Incident"?

NIS2 Art.40 does not define "large-scale cybersecurity incident" with precise thresholds. ENISA guidance identifies the following trigger factors:

Triggering Factors

Geographic scope: The incident affects entities or infrastructure in two or more member states simultaneously. A distributed denial-of-service attack targeting critical infrastructure across France, Germany, and the Netherlands would meet this criterion.

Sector criticality: The affected entities are essential entities in high-criticality sectors (Annex I: energy, transport, banking, health, water, digital infrastructure). The more critical the sector, the lower the threshold for escalation.

Societal or economic impact: The incident causes or risks causing significant disruption to essential services that citizens and economies depend on. Widespread outage of internet exchange infrastructure or backbone networks would qualify.

Supply chain reach: The incident involves software or hardware components used across multiple member states' critical infrastructure. The SolarWinds compromise (2020) and the XZ utils backdoor (2024) are examples where supply-chain incidents crossed the EU-CyCLONe activation threshold.

Recent Activation Examples

While EU-CyCLONe activation decisions are not always publicly disclosed in detail, the types of incidents that have prompted EU-level coordination include:

Developer Risk Scenarios

You may be indirectly part of an EU-CyCLONe event even if your own system is not the primary target:

  1. Cloud provider incident: Your essential-entity customer's cloud provider suffers an Art.23 significant incident that escalates to EU-CyCLONe. Your customer's NCA asks for information about how your software contributed to their exposure.

  2. OSS dependency incident: An open-source library you maintain or use widely is found to contain a critical vulnerability actively exploited across EU essential entities. EU-CyCLONe activation makes your vulnerability disclosure and patch timeline a matter of EU-level coordination.

  3. SaaS incident with multi-MS footprint: Your SaaS platform is used by essential entities in five member states. An incident affecting your platform triggers cross-border coordination even if individual national impacts fall below each country's Art.23 significant-incident threshold.

  4. CDN or DNS provider incident: A critical shared infrastructure provider you depend on becomes the subject of EU-CyCLONe coordination. Your NCA may ask what your contingency plan is and when you can restore service.


6. Python Example: Incident Escalation State Machine

The following illustrates how to model the NIS2 incident escalation levels, including EU-CyCLONe activation, in your incident response workflow:

from enum import Enum, auto
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from typing import Optional, List


class EscalationLevel(Enum):
    """NIS2 Art.23 + EU-CyCLONe escalation levels."""
    INTERNAL = auto()           # Not yet significant
    SIGNIFICANT = auto()        # Art.23 reporting triggered
    CSIRT_COORDINATED = auto()  # CSIRT Network involvement
    CYCLONE_ACTIVATED = auto()  # EU-CyCLONe cross-border coordination
    POLITICAL_LEVEL = auto()    # NIS Cooperation Group / EC involvement


@dataclass
class IncidentReportingDeadline:
    level: str
    deadline: datetime
    recipient: str
    content: str
    completed: bool = False


@dataclass
class NIS2Incident:
    incident_id: str
    detected_at: datetime
    escalation_level: EscalationLevel = EscalationLevel.INTERNAL
    affected_member_states: List[str] = field(default_factory=list)
    is_essential_entity: bool = True
    reporting_deadlines: List[IncidentReportingDeadline] = field(default_factory=list)
    cyclone_activation_suspected: bool = False

    def assess_escalation(
        self,
        cross_border_impact: bool,
        sector_criticality: str,  # "high" (Annex I) or "important" (Annex II)
        societal_impact_score: int,  # 0-10
    ) -> EscalationLevel:
        """
        Determine escalation level based on incident characteristics.
        """
        if not self.is_essential_entity and sector_criticality != "high":
            return EscalationLevel.INTERNAL

        if societal_impact_score >= 7:
            if cross_border_impact and len(self.affected_member_states) >= 2:
                self.cyclone_activation_suspected = True
                return EscalationLevel.CYCLONE_ACTIVATED
            return EscalationLevel.SIGNIFICANT

        if societal_impact_score >= 4:
            if cross_border_impact:
                return EscalationLevel.CSIRT_COORDINATED
            return EscalationLevel.SIGNIFICANT

        return EscalationLevel.INTERNAL

    def compute_reporting_deadlines(self) -> List[IncidentReportingDeadline]:
        """
        Compute Art.23 deadlines, with compressed timelines for CyCLONe scenarios.
        """
        deadlines = []

        if self.escalation_level == EscalationLevel.INTERNAL:
            return deadlines

        # Art.23(1) — Early warning: 24 hours
        deadlines.append(IncidentReportingDeadline(
            level="Art.23(1) Early Warning",
            deadline=self.detected_at + timedelta(hours=24),
            recipient="NCA + national CSIRT",
            content="Notification that significant incident occurred. "
                    "Initial classification. Whether malicious cause suspected.",
        ))

        # Art.23(2) — Initial notification: 72 hours
        deadlines.append(IncidentReportingDeadline(
            level="Art.23(2) Initial Notification",
            deadline=self.detected_at + timedelta(hours=72),
            recipient="NCA + national CSIRT",
            content="Initial assessment: severity, impact, indicators of compromise. "
                    "Cross-border impact assessment if applicable.",
        ))

        if self.cyclone_activation_suspected:
            # Supplementary report when CyCLONe coordination is active
            # No fixed Art.23 deadline, but NCAs request information in near-real-time
            deadlines.append(IncidentReportingDeadline(
                level="EU-CyCLONe Supplementary Report",
                deadline=self.detected_at + timedelta(hours=48),
                recipient="NCA (for relay to EU-CyCLONe channel)",
                content="Cross-border impact scope. Affected member states. "
                        "Estimated affected essential entities by sector. "
                        "Ongoing mitigation measures. Timeline to resolution.",
            ))

        # Art.23(4) — Final report: 1 month
        deadlines.append(IncidentReportingDeadline(
            level="Art.23(4) Final Report",
            deadline=self.detected_at + timedelta(days=30),
            recipient="NCA",
            content="Detailed description. Severity + duration. Impact. "
                    "Root cause. Cross-border effects. Measures taken + planned.",
        ))

        self.reporting_deadlines = deadlines
        return deadlines

    def get_next_deadline(self) -> Optional[IncidentReportingDeadline]:
        pending = [d for d in self.reporting_deadlines if not d.completed]
        if not pending:
            return None
        return min(pending, key=lambda d: d.deadline)

    def status_summary(self) -> dict:
        next_d = self.get_next_deadline()
        return {
            "incident_id": self.incident_id,
            "escalation_level": self.escalation_level.name,
            "cyclone_active": self.cyclone_activation_suspected,
            "affected_ms_count": len(self.affected_member_states),
            "next_deadline": next_d.level if next_d else "All complete",
            "next_deadline_at": next_d.deadline.isoformat() if next_d else None,
            "minutes_to_next_deadline": (
                int((next_d.deadline - datetime.now()).total_seconds() / 60)
                if next_d else None
            ),
        }


# Example: SaaS platform incident with cross-border impact
if __name__ == "__main__":
    incident = NIS2Incident(
        incident_id="INC-2026-0042",
        detected_at=datetime(2026, 4, 20, 9, 0, 0),
        affected_member_states=["DE", "FR", "NL"],
        is_essential_entity=True,
    )

    level = incident.assess_escalation(
        cross_border_impact=True,
        sector_criticality="high",
        societal_impact_score=8,
    )
    print(f"Escalation level: {level.name}")
    # Output: Escalation level: CYCLONE_ACTIVATED

    deadlines = incident.compute_reporting_deadlines()
    for d in deadlines:
        print(f"\n[{d.level}]")
        print(f"  Deadline: {d.deadline.strftime('%Y-%m-%d %H:%M')}")
        print(f"  To: {d.recipient}")

This state machine gives your incident response team a structured model for tracking which Art.23 obligations apply and whether EU-CyCLONe context creates additional reporting requirements.


7. The Peer Review → Enforcement Feedback Loop

Articles 39 and 40 interact in a way that developers should understand as a long-term enforcement pressure system:

Art.39 Peer Review                Art.40 EU-CyCLONe
       │                                  │
       ▼                                  ▼
NCA Gap Identified              Large-Scale Incident Occurs
(e.g., light supervision)       (e.g., cross-border attack)
       │                                  │
       ▼                                  ▼
NCA Action Plan Created         EU-CyCLONe AAR (After Action Review)
       │                                  │
       ▼                                  ▼
Increased NCA Enforcement       NIS Cooperation Group receives lessons
       │                                  │
       └──────────────┬───────────────────┘
                      ▼
              NIS Cooperation Group
              Updates Guidelines
                      │
                      ▼
         Updated NCA Supervision Practices
         (affects all regulated entities)

Each peer review cycle and each major EU-CyCLONe activation adds to the institutional memory of EU cybersecurity governance. Over time, this raises the enforcement floor for all NIS2 regulated entities.


8. Developer Checklist: Art.39 and Art.40 Preparedness

Art.39 Peer Review — Indirect Preparation

Art.40 EU-CyCLONe — Direct Operational Preparation


9. Art.39–40 in the NIS2 Compliance Journey

For most developers working on EU-regulated infrastructure, Articles 39 and 40 represent the outer edge of the NIS2 compliance envelope — the mechanisms that activate only when incidents exceed national capacity. Day-to-day compliance work focuses on Art.21 security measures, Art.23 incident reporting, and Art.32/33 supervisory cooperation.

But Art.39 and Art.40 define the ceiling conditions of the NIS2 regime — the point at which your incident stops being a bilateral conversation between you and your NCA and becomes an EU-coordinated response involving multiple governments and ENISA.

For developers building infrastructure used across multiple member states, cloud-hosted services, or widely-adopted open-source software, the probability of touching the Art.40 threshold is non-trivial. A single critical vulnerability in a broadly-deployed library, or a sustained attack on a multi-MS SaaS platform, can cross the EU-CyCLONe activation threshold.

The preparation required is not fundamentally different from standard incident response planning. The difference is scope: Art.40 preparation means extending your incident response plan to accommodate compressed timelines, multi-authority disclosure, and cross-border coordination — and knowing which of your dependencies could independently trigger the threshold even if your own systems are resilient.


10. EU Infrastructure Advantage

Running your production stack on EU-native infrastructure has a specific advantage in EU-CyCLONe scenarios that is worth naming explicitly.

When EU-CyCLONe coordinates a large-scale incident response, one of the information-sharing challenges is jurisdiction. US-headquartered cloud providers are subject to CLOUD Act requests from US authorities — requests that can legally conflict with the Art.38 confidentiality obligations governing information shared in the EU-CyCLONe channel.

An entity whose infrastructure is hosted on EU-native managed platforms — with no US parent company and no CLOUD Act exposure — operates under a cleaner legal framework during a EU-CyCLONe coordination event. There is no question about whether US subpoenas could extract information from the NCA coordination channel via a US-based infrastructure provider.

This does not replace Art.21 security measures or Art.23 reporting obligations. But it eliminates a class of jurisdictional conflicts that can complicate EU-CyCLONe coordination scenarios for entities running on US-headquartered infrastructure.


Conclusion

Articles 39 and 40 complete the NIS2 cross-border coordination architecture. Art.39 creates the feedback mechanism that raises NCA enforcement standards over time. Art.40 creates the operational crisis response infrastructure that activates when cybersecurity incidents exceed national capacity.

For developers and security engineers, the operative takeaways are:

  1. Post-review NCAs enforce more actively — know whether your NCA has undergone a peer review and what recommendations it received.
  2. EU-CyCLONe compresses Art.23 timelines — if your incident involves cross-border essential infrastructure, your NCA may request information on a timeline measured in hours.
  3. Your critical dependency map is your CyCLONe risk map — the cloud providers, CDNs, DNS operators, and OSS components you depend on determine your indirect CyCLONe exposure.
  4. Supplementary reporting templates save time — prepare them before you need them.
  5. Art.38 governs what CyCLONe does with your data — professional secrecy applies, but information reaches more authorities than in a standard Art.23 report.

The EU's cybersecurity coordination infrastructure is maturing. Articles 39 and 40 are how it learns from incidents and coordinates across borders when the next large-scale event occurs.


This post is part of the sota.io EU Developer Compliance Series. Next: NIS2 Chapter VII: International Cooperation and ENISA Support.