2026-04-16·15 min read·

EU Cyber Resilience Act + NIS2 Overlap: Dual Compliance Developer Guide (2026)

Two EU regulations now govern cybersecurity simultaneously — and if you build software products used in critical infrastructure, both apply to you.

NIS2 (Directive 2022/2555) has been in force since October 2024. It targets operators of essential and important services: the hospitals, energy providers, financial institutions, and cloud infrastructure companies that underpin EU society. NIS2 obligates these operators to implement risk management measures and report incidents.

CRA (Regulation 2024/2847, the Cyber Resilience Act) enters application in stages. Its vulnerability and incident reporting requirements become mandatory for manufacturers of products with digital elements from 11 September 2026 — less than five months away. Full technical requirements apply from 11 December 2027.

The overlap problem: if you build software that is both deployed as part of EU critical infrastructure (NIS2 scope) and shipped as a product with digital elements (CRA scope), you face dual obligations from the same incident. A single exploited vulnerability can trigger both a CRA 24-hour report to ENISA and a NIS2 24-hour early warning to your national competent authority — with different recipients, different forms, and different legal thresholds.

This guide maps the intersection.


1. Scope: Who Is Caught by Both

NIS2 Scope (Directive 2022/2555, Art.2–3)

NIS2 applies to essential entities (Art.3(1)) and important entities (Art.3(2)) in 18 critical sectors: energy, transport, banking, financial market infrastructure, health, drinking water, wastewater, digital infrastructure, public administration, and space (essential); plus postal, waste management, chemicals, food, manufacturing, and digital providers (important).

Cloud computing service providers are essential entities regardless of size (Art.2(2)). Managed service providers and managed security service providers can be essential or important entities under the digital infrastructure sector.

CRA Scope (Regulation 2024/2847, Art.2)

CRA applies to manufacturers of products with digital elements — hardware and software products whose intended purpose includes or requires connectivity. This covers:

The dual-scope zone: A SaaS platform that provides cloud services to essential entities (NIS2 Art.3) AND ships software components to downstream integrators (CRA Art.2) is subject to both regimes simultaneously.

Key Exclusion: CRA Art.2(6) for NIS2-Regulated Sectors

CRA Art.2(6) excludes products covered by sector-specific Union law that achieves an equivalent level of protection — but the exclusion is narrow and conditional. For the financial sector, DORA (Regulation 2022/2554) provides the exclusion pathway. For healthcare devices, MDR and IVDR. But general-purpose cloud platforms, developer tools, and software products do not benefit from this exclusion unless a specific sectoral instrument says otherwise. Most SaaS and PaaS operators will be subject to both CRA and NIS2.


2. Vulnerability Reporting: The Clock Conflict

This is the most operationally urgent overlap because the CRA reporting obligation activates in September 2026.

CRA Art.14: Manufacturer Vulnerability Reporting

CRA Art.14(1) requires manufacturers to notify ENISA (via the Single Reporting Platform) of:

CRA Art.14(3) extends the same reporting obligation to significant incidents affecting the security of the product with digital elements — a deliberate echo of NIS2's incident framing.

The recipient is ENISA, which coordinates with national CSIRTs.

NIS2 Art.23: Operator Incident Reporting

NIS2 Art.23(4) requires essential and important entities to notify their national competent authority (NCA) or CSIRT of significant incidents:

The recipient is the national NCA/CSIRT, not ENISA directly — though NCAs share data via the NIS Cooperation Group.

The Clock Conflict in Practice

When an actively exploited vulnerability in your software affects a NIS2-covered entity that runs your software:

ObligationRecipientClock startsDeadline
CRA Art.14(2)(a)ENISA Single Reporting PlatformManufacturer becomes aware of exploitation24 hours
NIS2 Art.23(4)(a)National NCA/CSIRTOperator becomes aware of significant incident24 hours
CRA Art.14(2)(b)ENISAAwareness72 hours
NIS2 Art.23(4)(b)National NCA/CSIRTAwareness72 hours

Critical point: "Becoming aware" does not synchronise automatically. The manufacturer may learn of exploitation from a researcher report. The operator may learn from their SIEM. The clocks are independent. In practice, close coordination between your security and product teams is essential — the manufacturer's CRA clock and the operator's NIS2 clock should start at the same time if you are both, or you will miss one of them.

Conflicting content requirements: The CRA report focuses on the product vulnerability — CVE identifier, affected versions, patch status. The NIS2 report focuses on the service impact — affected services, estimated number of users affected, disruption duration. Your incident response process must generate both formats from the same incident data.


3. Security Requirements Overlap: CRA Art.13 vs NIS2 Art.21

Both CRA and NIS2 impose baseline security requirements. They overlap substantially but have different framings.

CRA Art.13: Security Requirements for Products

CRA Annex I Part I defines mandatory security requirements for products with digital elements. Manufacturers must ensure products:

CRA Annex I Part II adds ongoing vulnerability handling obligations:

NIS2 Art.21: Risk Management Measures

NIS2 Art.21(2) requires operators to implement ten minimum measures (covered in depth in the NIS2 Art.21 Developer Guide):

(a) Risk analysis and IS security policies
(b) Incident handling
(c) Business continuity, BCM, DR
(d) Supply chain security
(e) Secure SDLC, network security, vulnerability handling
(f) Effectiveness assessment (pentest, audit)
(g) Cyber hygiene and awareness
(h) Cryptography and key management
(i) HR security, access control, asset management
(j) MFA and encrypted communications

Overlap Map

Security DomainCRA RequirementNIS2 RequirementOverlap Strategy
Vulnerability disclosureArt.14(4): CVD policy mandatoryArt.21(2)(e): CVD mandatorySingle CVD policy satisfies both. Ensure CRA ENISA report and NIS2 NCA report generated from same CVD workflow
Supply chain securityAnnex I.1: no known vulns at supplyArt.21(2)(d): ICT supplier securitySBOM (CRA Art.13(13)) feeds NIS2 supplier inventory. CRA SBOM satisfies NIS2 Art.21(2)(d) documentation requirement
Authentication and access controlAnnex I.1(3): appropriate auth per security riskArt.21(2)(j): MFA mandatory for remote accessCRA is risk-proportionate; NIS2 MFA is mandatory. Implement NIS2 MFA — it satisfies CRA Annex I.1(3)
Secure SDLCAnnex I.1(7): updatable design; no vulns at releaseArt.21(2)(e): secure SDLCCRA product-level SDLC requirements and NIS2 operational SDLC requirements can be unified in one secure development framework
Incident responseArt.14: report exploited vulnsArt.21(2)(b): incident handling proceduresDual-track reporting required. Single IR playbook, dual notification paths
Data protection in transit/restAnnex I.1(4): confidentiality and integrityArt.21(2)(h): cryptography policyUnified encryption policy satisfies both

4. Supply Chain Layering: CRA Manufacturer + NIS2 Operator

The most complex scenario arises in supply chains where:

  1. Your customer is a NIS2 essential entity (e.g., a hospital, energy provider, or cloud infrastructure operator)
  2. You supply them software as a product with digital elements (CRA applies to you as manufacturer)
  3. Your customer uses your software as part of their NIS2-covered operations (NIS2 Art.21(2)(d) requires them to assess your security)

Under NIS2 Art.21(2)(d), your customer must evaluate:

Under CRA, you must:

Practical requirement: To satisfy your NIS2-covered customers' Art.21(2)(d) supply chain due diligence requirements, you will need to provide:

Your CRA compliance documentation becomes the evidence your NIS2-covered customers need. Build these artefacts together.


5. Fines: Double Exposure

RegulationFine (max)Basis
CRA Art.64(4) — severe product requirements breach€15 million or 2.5% global annual turnoverWhichever is higher
CRA Art.64(5) — other product requirements breach€10 million or 2% global annual turnoverWhichever is higher
CRA Art.64(6) — incorrect/incomplete information€5 million or 1% global annual turnoverWhichever is higher
NIS2 Art.32 (essential entity)€10 million or 2% global annual turnoverWhichever is higher
NIS2 Art.33 (important entity)€7 million or 1.4% global annual turnoverWhichever is higher

An operator of a cloud platform serving critical infrastructure that also manufactures products with digital elements can face simultaneous enforcement actions under CRA (market surveillance authorities) and NIS2 (national competent authorities). These are different supervisory bodies — coordination is expected but not guaranteed.

Enforcement timing: CRA market surveillance authorities are currently being designated by Member States (deadline: December 2025). NIS2 NCAs are already active. From September 2026, both enforcement regimes will be simultaneously live.


6. Python CRANis2ComplianceMapper

from dataclasses import dataclass, field
from enum import Enum
from typing import Optional
from datetime import datetime, timezone

class EntityRole(Enum):
    CRA_MANUFACTURER = "cra_manufacturer"       # Ships products with digital elements
    NIS2_ESSENTIAL = "nis2_essential"           # Essential entity operator
    NIS2_IMPORTANT = "nis2_important"           # Important entity operator
    DUAL_MANUFACTURER_OPERATOR = "dual"         # Both CRA and NIS2 apply

class IncidentSeverity(Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    CRITICAL = "critical"

@dataclass
class SecurityIncident:
    incident_id: str
    description: str
    severity: IncidentSeverity
    detected_at: datetime
    exploited_vulnerability: bool = False
    affects_nis2_services: bool = False
    affected_users_count: int = 0
    personal_data_involved: bool = False

@dataclass
class ReportingObligation:
    regulation: str
    obligation: str
    recipient: str
    deadline_hours: int
    triggered: bool
    rationale: str
    deadline_at: Optional[datetime] = None

@dataclass
class ComplianceRequirement:
    domain: str
    cra_requirement: Optional[str]
    nis2_requirement: Optional[str]
    unified_control: str
    gap: Optional[str] = None

class CRANis2ComplianceMapper:
    """Maps CRA + NIS2 dual compliance obligations for organisations subject to both."""

    def __init__(self, roles: list[EntityRole]):
        self.roles = roles
        self.is_cra_manufacturer = EntityRole.CRA_MANUFACTURER in roles or EntityRole.DUAL_MANUFACTURER_OPERATOR in roles
        self.is_nis2_operator = (
            EntityRole.NIS2_ESSENTIAL in roles
            or EntityRole.NIS2_IMPORTANT in roles
            or EntityRole.DUAL_MANUFACTURER_OPERATOR in roles
        )

    def assess_incident_reporting(self, incident: SecurityIncident) -> list[ReportingObligation]:
        """Determine all reporting obligations triggered by a security incident."""
        obligations = []

        # CRA Art.14(2)(a): Exploited vulnerability — 24h to ENISA
        if self.is_cra_manufacturer and incident.exploited_vulnerability:
            obligations.append(ReportingObligation(
                regulation="CRA Art.14(2)(a)",
                obligation="Report actively exploited vulnerability to ENISA Single Reporting Platform",
                recipient="ENISA (via Single Reporting Platform at euvdb.europa.eu)",
                deadline_hours=24,
                triggered=True,
                rationale="CRA requires manufacturers to notify ENISA of actively exploited vulnerabilities within 24h",
                deadline_at=incident.detected_at.replace(tzinfo=timezone.utc) if incident.detected_at.tzinfo is None
                           else incident.detected_at
            ))

        # CRA Art.14(2)(b): Severity assessment — 72h to ENISA
        if self.is_cra_manufacturer and incident.exploited_vulnerability:
            obligations.append(ReportingObligation(
                regulation="CRA Art.14(2)(b)",
                obligation="Submit severity assessment and initial CVE/vulnerability details to ENISA",
                recipient="ENISA Single Reporting Platform",
                deadline_hours=72,
                triggered=True,
                rationale="72-hour assessment required for exploited vulnerabilities under CRA Art.14(2)(b)"
            ))

        # NIS2 Art.23(4)(a): Significant incident early warning — 24h to NCA/CSIRT
        nis2_significant = (
            self.is_nis2_operator
            and incident.affects_nis2_services
            and incident.severity in (IncidentSeverity.HIGH, IncidentSeverity.CRITICAL)
        )
        if nis2_significant:
            obligations.append(ReportingObligation(
                regulation="NIS2 Art.23(4)(a)",
                obligation="Submit early warning of significant incident to national NCA/CSIRT",
                recipient="National Competent Authority or CSIRT",
                deadline_hours=24,
                triggered=True,
                rationale="NIS2 requires early warning within 24h for significant incidents affecting essential/important services"
            ))

        # NIS2 Art.23(4)(b): Incident notification — 72h to NCA/CSIRT
        if nis2_significant:
            obligations.append(ReportingObligation(
                regulation="NIS2 Art.23(4)(b)",
                obligation="Submit incident notification with severity, impact, and IoCs to national NCA/CSIRT",
                recipient="National Competent Authority or CSIRT",
                deadline_hours=72,
                triggered=True,
                rationale="72-hour incident notification with full initial assessment required under NIS2 Art.23(4)(b)"
            ))

        # GDPR Art.33: Personal data breach — 72h to DPA (if personal data involved)
        if self.is_nis2_operator and incident.personal_data_involved:
            obligations.append(ReportingObligation(
                regulation="GDPR Art.33",
                obligation="Notify supervisory authority (DPA) of personal data breach",
                recipient="National Data Protection Authority",
                deadline_hours=72,
                triggered=True,
                rationale="Personal data involvement triggers GDPR Art.33 notification in addition to NIS2 Art.23"
            ))

        return obligations

    def map_security_requirements(self) -> list[ComplianceRequirement]:
        """Generate unified compliance requirement map for CRA + NIS2."""
        requirements = [
            ComplianceRequirement(
                domain="Vulnerability Disclosure (CVD)",
                cra_requirement="Art.14(4): Publish CVD policy; coordinate disclosure with ENISA",
                nis2_requirement="Art.21(2)(e): CVD policy for network and information systems",
                unified_control="Single CVD policy covering both product vulnerabilities (CRA) and operational vulnerabilities (NIS2). Both require coordinated disclosure — one policy satisfies both."
            ),
            ComplianceRequirement(
                domain="SBOM and Dependency Tracking",
                cra_requirement="Art.13(13): Machine-readable SBOM for each product with digital elements",
                nis2_requirement="Art.21(2)(d): ICT supplier security — requires knowing what software components you run",
                unified_control="SBOM generated per CRA Art.13(13) satisfies NIS2 Art.21(2)(d) supplier inventory documentation requirement for software components."
            ),
            ComplianceRequirement(
                domain="Authentication and MFA",
                cra_requirement="Annex I.1(3): Appropriate authentication controls proportionate to risk",
                nis2_requirement="Art.21(2)(j): MFA mandatory for all remote access to network and information systems",
                unified_control="Implement NIS2 MFA (mandatory floor). CRA Annex I.1(3) is risk-proportionate — NIS2 MFA satisfies it. Deploy FIDO2/WebAuthn for essential entity classification."
            ),
            ComplianceRequirement(
                domain="Incident Response Procedures",
                cra_requirement="Art.14: Report exploited vulns to ENISA within 24h/72h/14d",
                nis2_requirement="Art.21(2)(b): Incident handling procedures; Art.23 notification to NCA",
                unified_control="Single IR playbook with dual notification paths. Incident detection triggers both CRA ENISA report (manufacturer path) and NIS2 NCA report (operator path) from same event data.",
                gap="Different recipients, forms, and required data. Automation needed to generate both from same incident record."
            ),
            ComplianceRequirement(
                domain="Supply Chain Security",
                cra_requirement="Annex I.1(1): No known exploitable vulns in components at time of supply",
                nis2_requirement="Art.21(2)(d): Assess ICT suppliers — security practices, contractual security requirements",
                unified_control="Supplier security programme with: (1) incoming SBOM review for CRA compliance, (2) contractual security requirements per NIS2 Art.21(2)(d), (3) periodic supplier reassessment."
            ),
            ComplianceRequirement(
                domain="Cryptography Policy",
                cra_requirement="Annex I.1(4): Protect confidentiality and integrity of data in transit and at rest",
                nis2_requirement="Art.21(2)(h): Policy on cryptography and encryption; key management",
                unified_control="Unified encryption policy: TLS 1.3 for transit, AES-256 for at-rest, key management procedures. CRA and NIS2 requirements fully overlap — one policy document satisfies both."
            ),
            ComplianceRequirement(
                domain="Security Updates and Patch Management",
                cra_requirement="Art.13(8): Security updates for minimum 5 years (or expected product lifetime); free of charge",
                nis2_requirement="Art.21(2)(e): Systematic vulnerability handling and patching; NIS2 CG sector guidelines specify timelines",
                unified_control="Patch management policy covering: (1) CRA product update cadence (5-year commitment), (2) NIS2 operational patch SLAs (ENISA recommends critical: 48h, high: 7d, medium: 30d).",
                gap="CRA 5-year support commitment requires long-term product roadmap planning that NIS2 operational patching does not."
            ),
            ComplianceRequirement(
                domain="Risk Assessment",
                cra_requirement="Art.13(2): Security risk assessment for each product; documented in technical file",
                nis2_requirement="Art.21(2)(a): Risk analysis of network and information systems; policy on IS security",
                unified_control="Unified risk assessment framework: product-level (CRA technical file) feeds into operational risk assessment (NIS2 Art.21(2)(a)). Same threat models, asset registry, and risk treatment documentation."
            ),
        ]
        return requirements

    def generate_compliance_report(self) -> dict:
        """Generate a summary compliance gap analysis."""
        requirements = self.map_security_requirements()
        gaps = [r for r in requirements if r.gap]
        unified = [r for r in requirements if not r.gap]

        return {
            "roles": [r.value for r in self.roles],
            "cra_manufacturer": self.is_cra_manufacturer,
            "nis2_operator": self.is_nis2_operator,
            "total_domains": len(requirements),
            "unified_controls": len(unified),
            "gaps_requiring_dual_effort": len(gaps),
            "gaps": [{"domain": g.domain, "gap": g.gap} for g in gaps],
            "reporting_obligations_activated_by_exploited_vuln_in_nis2_service": 5,
            "highest_fine_exposure": "EUR 15M or 2.5% global turnover (CRA Art.64(4) severe breach)",
        }


# Example usage
if __name__ == "__main__":
    # Organisation that both manufactures SaaS (CRA) and operates cloud infrastructure for NIS2 entities
    mapper = CRANis2ComplianceMapper(roles=[EntityRole.DUAL_MANUFACTURER_OPERATOR])

    # Simulate a critical incident
    incident = SecurityIncident(
        incident_id="INC-2026-001",
        description="Remote code execution vulnerability actively exploited in production",
        severity=IncidentSeverity.CRITICAL,
        detected_at=datetime(2026, 9, 15, 10, 0, 0),
        exploited_vulnerability=True,
        affects_nis2_services=True,
        affected_users_count=500,
        personal_data_involved=True,
    )

    print("=== Incident Reporting Obligations ===")
    for obligation in mapper.assess_incident_reporting(incident):
        print(f"\n[{obligation.regulation}]")
        print(f"  Action: {obligation.obligation}")
        print(f"  Recipient: {obligation.recipient}")
        print(f"  Deadline: {obligation.deadline_hours}h from detection")

    print("\n=== Compliance Gap Analysis ===")
    report = mapper.generate_compliance_report()
    print(f"Unified controls: {report['unified_controls']}/{report['total_domains']}")
    print(f"Gaps requiring dual effort: {report['gaps_requiring_dual_effort']}")
    for gap in report["gaps"]:
        print(f"  - {gap['domain']}: {gap['gap']}")

7. Key Dates for 2026

DateEvent
11 September 2026CRA vulnerability and incident reporting obligations (Art.14) become mandatory for manufacturers
June 2026NIS2 first-wave supervisory inspections expected in most Member States (NCA active enforcement)
December 2025Member States must designate CRA market surveillance authorities
11 December 2027CRA full technical requirements (Annex I) become mandatory; conformity assessment required
2027 onwardsCRA conformity assessment required before placing products on EU market

The September 2026 cliff: CRA Art.14 reporting becomes enforceable in five months. If you manufacture software products used by NIS2-covered entities and do not yet have a process to report exploited vulnerabilities to ENISA within 24 hours, that is the first gap to close.


8. 28-Item Dual Compliance Checklist

CRA Manufacturer Obligations (by Sept 2026 / Dec 2027)

NIS2 Operator Obligations

Dual CRA + NIS2 Unified Controls


See Also