Sunday, 20 September 2026

Cisco ACI Contract Exceptions vs Subject Exceptions Explained with Examples and Configuration Guide

Introduction

Cisco ACI contracts are used to control communication between Endpoint Groups (EPGs). They provide application-centric security by defining which EPGs can communicate and what traffic is permitted.

In large-scale environments, a single contract may be consumed by many EPGs. However, there are situations where certain EPGs must be excluded from using that contract without creating multiple duplicate contracts.

To solve this challenge, Cisco introduced Contract Exceptions and Subject Exceptions in APIC Release 3.2(1).

These features allow administrators to selectively deny contract participation while maintaining a clean, scalable, and easy-to-manage policy model.


Why Contract Exceptions and Subject Exceptions Are Needed

Consider a production application environment with the following EPGs:

Consumer EPGs:

  • Web-EPG
  • App-EPG
  • Reporting-EPG
  • Test-EPG

Provider EPG:

  • Database-EPG

Contract:

  • DB-Access

Normally all consumer EPGs can access the database through the contract.

Web-EPG → Database-EPG

App-EPG → Database-EPG

Reporting-EPG → Database-EPG

Test-EPG → Database-EPG

Now assume the security team decides that Test-EPG should not access the production database.

Without Contract Exceptions, you would need to create additional contracts and duplicate policies.

With Contract Exceptions, you can simply exclude Test-EPG from participating in the contract.


What is a Contract Exception?

A Contract Exception selectively excludes an EPG from participating in a contract.

The key point is that the exception applies to ALL subjects within the contract.

For example:

Contract Name: DB-Access

Subjects:

  • SQL
  • Backup
  • Monitoring

If Test-EPG is configured as a Contract Exception, it will be denied access to every subject under the contract.

Result:

  • Web-EPG = Allowed
  • App-EPG = Allowed
  • Reporting-EPG = Allowed
  • Test-EPG = Denied

This is useful when an EPG should be completely excluded from the contract.


What is a Subject Exception?

A Subject Exception applies only to a specific subject inside a contract.

Instead of blocking an entire contract, it blocks access only to a particular service.

For example:

Contract Name: Shared-Services

Subjects:

  • HTTP
  • HTTPS
  • SQL
  • DNS

Requirement:

  • HTTP = Allowed
  • HTTPS = Allowed
  • DNS = Allowed
  • SQL = Denied

In this scenario, a Subject Exception is the ideal solution because only the SQL subject needs to be restricted.


Contract Exception vs Subject Exception

Contract Exception affects the entire contract.

Subject Exception affects only a single subject.

Contract Exception is used when an EPG must be excluded completely.

Subject Exception is used when only specific services must be denied.

Contract Exception provides broader control.

Subject Exception provides finer granular control.


Real-World Production Example

Consider a banking environment.

Consumer EPGs:

  • Internet-Web
  • Mobile-App
  • ATM-Services
  • Audit-Tools

Provider EPG:

  • Database-EPG

Contract:

  • Database-Access

Business Requirement:

  • Internet-Web = Allowed
  • Mobile-App = Allowed
  • ATM-Services = Allowed
  • Audit-Tools = Denied

Without Contract Exceptions, multiple contracts would be required.

Database-Access

Database-Access-NoAudit

Database-Access-ATM

Database-Access-Web

This creates unnecessary complexity.

A better design is:

One shared Database-Access contract plus a Contract Exception for Audit-Tools.

This reduces contract sprawl and simplifies management.


Cisco ACI Contract Exception Configuration

Objective

Allow:

  • Web-EPG
  • App-EPG
  • Reporting-EPG

Deny:

  • Test-EPG

For the DB-Access contract.

Step 1: Create the Contract

Navigate to:

Tenant → Contracts → Standard → Create Contract

Configure:

Contract Name: DB-Access

Scope: Tenant

Step 2: Create a Subject

Open the DB-Access contract.

Navigate to:

Subjects → Create Subject

Configure:

Subject Name: SQL

Step 3: Create a Filter

Create a filter with:

Protocol: TCP

Destination Port: 1433

Action: Permit

Attach the filter to the SQL subject.

Step 4: Provide the Contract

Navigate to Database-EPG.

Under Provided Contracts, attach DB-Access.

Step 5: Consume the Contract

Navigate to:

  • Web-EPG
  • App-EPG
  • Reporting-EPG
  • Test-EPG

Attach DB-Access as a Consumed Contract.

At this stage all EPGs can access the database.

Step 6: Create Contract Exception

Navigate to:

Tenant → Contracts → DB-Access → Exceptions

Click Create Exception.

Configure:

Exception Name: Block-Test-EPG

Consumer EPG: Test-EPG

Save and Deploy.

Final Result

  • Web-EPG → Allowed
  • App-EPG → Allowed
  • Reporting-EPG → Allowed
  • Test-EPG → Denied

Because the exception is configured at the contract level, all subjects are affected.


Cisco ACI Subject Exception Configuration

Objective

Allow Web-EPG to access:

  • HTTP
  • HTTPS
  • DNS

Deny access to:

  • SQL

Step 1: Create Contract

Create a contract called Shared-Services.

Step 2: Create Subjects

Create the following subjects:

  • HTTP
  • HTTPS
  • SQL
  • DNS

Step 3: Attach Filters

HTTP Subject:

TCP Port 80

Permit

HTTPS Subject:

TCP Port 443

Permit

SQL Subject:

TCP Port 1433

Permit

DNS Subject:

UDP Port 53

Permit

Step 4: Create Subject Exception

Navigate to:

Shared-Services → Subject SQL → Exceptions

Click Create Exception.

Configure:

Exception Name: Web-No-SQL

EPG: Web-EPG

Save and Deploy.

Final Result

For Web-EPG:

  • HTTP → Allowed
  • HTTPS → Allowed
  • DNS → Allowed
  • SQL → Denied

Other EPGs continue to access SQL if no Subject Exception exists for them.


How Packet Processing Works

When traffic is initiated:

Step 1: Cisco ACI identifies the source EPG.

Step 2: Cisco ACI identifies the destination EPG.

Step 3: Contract lookup is performed.

Step 4: Subject filters are evaluated.

Step 5: Contract and Subject Exceptions are checked.

Step 6: Traffic is either permitted or denied.

This enables very granular policy enforcement within the ACI fabric.


Logging and Visibility Features

Contract Exceptions and Subject Exceptions support:

Labels

Useful for policy identification.

Examples:

  • Production-SQL
  • PCI-Restricted
  • Database-Security

Counters

Used to track:

  • Permit Hits
  • Deny Hits
  • Bytes
  • Packets

Permit and Deny Logging

Helpful during troubleshooting and audits.

Administrators can determine whether traffic was blocked due to:

  • Contract Exception
  • Subject Exception
  • Deny Filter
  • Missing Contract

Troubleshooting Tips

Verify zoning rules using:

show zoning-rule scope tenant

Monitor contract counters from:

Tenant → Operations → Counters → Contracts

Review:

  • Permit Hits
  • Deny Hits
  • Packet Counts
  • Byte Counts

Check Events and Faults under:

Operations → Events

Operations → Faults

This helps quickly identify policy-related connectivity issues.


Design Best Practices

Use Contract Exceptions when:

  • Development EPGs must be blocked completely.
  • Test EPGs must be isolated.
  • Audit environments should not reach production systems.
  • Temporary projects require full exclusion.

Use Subject Exceptions when:

  • HTTP should be allowed but SQL denied.
  • HTTPS should be allowed but SSH denied.
  • DNS should be allowed but ICMP denied.

Avoid creating multiple duplicate contracts.

Instead of:

Web-To-DB

App-To-DB

ATM-To-DB

Audit-To-DB

Use:

Shared Database Contract

Plus

Contract Exception or Subject Exception

This creates a simpler and more scalable design.


Interview Questions

Q1. What is the difference between Contract Exception and Subject Exception?

Contract Exception applies to the entire contract and affects all subjects. Subject Exception applies only to a specific subject within the contract.

Q2 Can Contract Exceptions be configured for both Providers and Consumers?

Yes. Contract Exceptions can exclude both provider and consumer EPGs.

Q3. When should Subject Exceptions be used?

When only specific application services need to be denied while allowing other services within the same contract.

Q4. Which APIC release introduced Contract and Subject Exceptions?

APIC Release 3.2(1).

Q5. What is the main benefit of Contract Exceptions?

They reduce contract sprawl and simplify policy management.


Key Takeaways

  • Contract Exceptions apply to the entire contract.
  • Subject Exceptions apply to a specific subject only.
  • Both features were introduced in APIC 3.2(1).
  • They help implement granular micro-segmentation.
  • They reduce the need for duplicate contracts.
  • Logging, counters, labels, and deny/permit monitoring are fully supported.
  • They improve scalability and operational simplicity in large Cisco ACI deployments.

Conclusion

Contract Exceptions and Subject Exceptions are powerful Cisco ACI features that help architects implement flexible micro-segmentation policies without increasing configuration complexity. Contract Exceptions are ideal when an EPG must be excluded from an entire contract, while Subject Exceptions are best suited for restricting access to specific services within a contract. By using these features effectively, organizations can simplify policy management, reduce contract sprawl, improve security, and maintain a cleaner ACI policy model across the fabric.

Recommended for: CCNP Data Center, CCIE Data Center, ACI Administrators, Data Center Engineers, Network Architects, and anyone designing secure Cisco ACI environments.


Summary


Related Links

  • Cisco ACI MoQuery – Advanced Commands for Day-to-Day Operations
    Useful for verifying contracts, providers/consumers, subjects, filters, and Taboo contracts.
    Read the MoQuery guide
  • What is a Contract Preferred Group in ACI?
    Related to ACI contract policy and EPG communication within a VRF.
    Read the Contract Preferred Group guide
  • Cisco ACI Explained: Concepts, Learning Prerequisites, Benefits, and Limitations
    Provides a broader introduction to ACI contracts, EPGs, filters, and the deny-by-default model.
    Read the Cisco ACI guide
  • Top 10 Cisco ACI Multiple Choice Questions (MCQs)
    Useful for reinforcing contract scope, filter direction, consumer/provider relationships, and vzAny.
    Read the ACI MCQs
  • L3Out Subnet Scope Options in Cisco ACI
    Useful as a related policy/security topic, particularly for understanding external EPG security import subnets and contract-based traffic control.
    Read the L3Out Subnet Scope guide

  • Saturday, 12 September 2026

    Cisco ACI: How Overlapping L3Out Subnets Silently Hijack Contracts

    If you run multiple L3Outs in the same VRF on Cisco ACI, there's a classification behavior that catches a lot of engineers off guard: external EPG classification is done per-VRF, not per-L3Out. That single fact can cause traffic from one L3Out to get tagged — and policed — as if it came from a completely different one.

    I ran into this in the lab and wanted to break it down in plain terms, because the failure mode is sneaky: everything can look and even work fine, right up until it doesn't.

    The Lab Topology

    Two leaf switches, one VRF, two L3Outs:

    • Leaf-101 — OSPF L3Out on interface eth1/22 (192.168.48.1/24), external EPG pcTag 16387
    • Leaf-102 — EIGRP L3Out on an SVI (192.168.47.1/24), external EPG pcTag 16386
    • An App EPG (pcTag 49153) sitting on Leaf-101, with an endpoint at 192.168.1.17/24

    OSPF is advertising a host route, 192.168.9.6/32. EIGRP is advertising 192.168.9.1/32. On the EIGRP L3Out, the admin has flagged 192.168.9.0/24 as "External Subnet for External EPG" — a common shortcut to catch a whole range of addresses under one external EPG instead of listing every host route.

    Here's the setup visually:


    What ACI Actually Does With That /24

    This is the part that trips people up. In ACI, an external (L3Out) EPG isn't classified by which physical L3Out or interface the packet arrived on — it's classified by a longest-prefix-match (LPM) lookup against a single table shared by the whole VRF. Every leaf switch running that VRF gets a copy of the same prefix-to-pcTag table.

    So the moment 192.168.9.0/24 gets programmed as "external subnet for external EPG" under the EIGRP external EPG, that entry doesn't just live on Leaf-102. It gets pushed to every leaf in the VRF, including Leaf-101 — the one that only knows about OSPF.

    Where It Goes Wrong

    Before any contract touches the EIGRP external EPG, Leaf-101 only has a generic 0.0.0.0/0 catch-all entry in its prefix table. Traffic from 192.168.9.6 (the OSPF route) matches that default and gets classified correctly as OSPF's external EPG (16387). No drama.

    Add just one contract anywhere that references the EIGRP external EPG — even a contract to something entirely unrelated to Leaf-101 — and ACI pushes the 192.168.9.0/24 entry into Leaf-101's classification table too.

    Now watch what happens to traffic sourced from 192.168.9.6 hitting Leaf-101 via the OSPF L3Out:

    • 192.168.9.6 matches both the OSPF default route (0.0.0.0/0) and the new EIGRP entry (192.168.9.0/24)
    • LPM always wins with the more specific prefix
    • /24 beats /0, so the packet gets tagged with pcTag 16386 (EIGRP) — not 16387 (OSPF), even though it arrived over the OSPF L3Out and has nothing to do with EIGRP

    The switch isn't misbehaving. It's doing exactly what LPM tables are supposed to do. The problem is that two unrelated EPGs ended up sharing address space in a VRF-wide table.

    Why It Doesn't Always Blow Up Immediately

    In my test, a ping from 192.168.9.6 to the App EPG endpoint still succeeded — even with no contract explicitly permitting OSPF-to-App traffic. Why? Because the traffic got misclassified as EIGRP (16386), and a contract already existed between the EIGRP external EPG and the App EPG. Wrong tag, right permission — so it slipped through.

    That's the dangerous part: the traffic looks fine on the surface, but it's being permitted for the wrong reason. And the only reason it worked at all in this lab comes down to one coincidence — which is worth unpacking on its own.

    Scenario 2: Add a Third Leaf and the "Lucky Pass" Disappears

    The reason the misclassified ping went through in the two-leaf lab is that the App EPG endpoint happened to live on the same leaf (Leaf-101) where the misclassification occurred. ACI doesn't blast every zoning-rule to every leaf in the fabric — a rule only gets programmed onto the leaves where it's actually needed, based on where the relevant EPGs have local significance (an endpoint, a BD, or an L3Out). Leaf-101 already needed the pcTag 16386 ↔ 49153 rule locally, since it happened to host the App EPG endpoint too — so the misdirected OSPF traffic rode along on a rule that was only there for an unrelated reason.

    Now change one thing: put the App EPG endpoint on a separate, third leaf (Leaf-103) instead of Leaf-101. The traffic path looks like this:





    Here's what happens:

    • Traffic from 192.168.9.6 still enters through Leaf-101 (the OSPF border leaf) and still gets misclassified as pcTag 16386, for the exact same LPM reason as before.
    • Policy enforcement in this VRF happens on ingress, so the permit/deny decision for that traffic is made right there on Leaf-101 — before it ever reaches Leaf-103.
    • The zoning-rule for pcTag 16386 ↔ 49153 exists on Leaf-103 (which hosts the App EPG endpoint) and on Leaf-102 (which owns the EIGRP L3Out and enforces policy for return traffic heading back out). Neither of those is Leaf-101.
    • Leaf-101 has no local reason to carry that specific rule, so the misclassified traffic hits the implicit deny at the ingress leaf and is silently dropped — never even reaching Leaf-103.

    So the exact same misclassification bug produces two different outcomes purely based on physical placement of the endpoint: a false "it works" when the endpoint and the misclassifying leaf are the same box, and a silent drop once you scale out to more leaves — which is the normal, realistic case in production. That's what makes this bug so easy to miss in a small lab and so painful to chase down later in a real fabric.

    How to Actually Confirm This Is Happening

    Three places to check on the leaf CLI:

    1. show zoning-rule scope <vrf-vnid> — shows the actual permit/deny rules per pcTag pair (ACI's ACL equivalent).
    2. show system internal policy-mgr prefix — shows what prefixes are currently mapped to which pcTag on that specific leaf. This is where you'll catch the 192.168.9.0/24 → 16386 entry showing up on a leaf that shouldn't care about EIGRP at all.
    3. ELAM (Embedded Logic Analyzer Module) — trigger a capture on the source IP and check the sclass field in the report. If it shows the EIGRP pcTag for OSPF-sourced traffic, that's your smoking gun.

    The Takeaway

    Don't let external subnets marked "External Subnet for External EPG" overlap across L3Outs that share a VRF. Even if the L3Outs are on completely different leaves, different routing protocols, and different interfaces, the classification table doesn't care — it's VRF-wide.

    A few practical guardrails:

    • Keep external subnet ranges assigned per L3Out non-overlapping wherever possible.
    • Avoid broad "catch-all" subnets (like a /24) on an external EPG unless you're certain no other L3Out in the same VRF will ever advertise something inside that range.
    • Before adding a new contract involving an external EPG, check show system internal policy-mgr prefix on the other leaves in the VRF to see what it's about to push fabric-wide.
    • If a ping or flow "just works," don't assume it worked through the contract you think it did — verify the pcTag with ELAM if something feels off.
    • Don't trust a passing test in a small lab as proof the design is safe — a "lucky pass" caused by endpoint placement on a single leaf can mask a bug that fails as soon as you scale to more leaves.

    Related Reading