Auto Draft

STP and RSTP on Cisco Catalyst Switches: A Deep Dive into Spanning Tree

Spanning Tree Protocol has been the backbone of loop-free Layer 2 networks for decades, yet it remains one of the most misunderstood and poorly-deployed protocols in enterprise environments. I’ve seen spanning tree misconfigurations take down entire campuses — silent topology changes, rogue root bridges, and port flapping that nobody notices until half the building loses connectivity. This guide walks through STP and RSTP on Cisco Catalyst switches with the CLI commands you’ll actually use, the show output you need to interpret, and the design decisions that separate a stable network from a time bomb.

STP vs. RSTP: What Actually Changed

Classic 802.1D STP introduced in 1985 uses a 30-second convergence timer by default (15s listening + 15s learning). In a modern network this is unacceptable. RSTP (802.1w) — now the default on all Cisco Catalyst switches — drops convergence to under a second by introducing proposal/agreement handshaking between adjacent switches and eliminating the listening state entirely.

On IOS-XE, RSTP runs as Rapid PVST+ (Per-VLAN Spanning Tree Plus), which maintains a separate STP instance per VLAN. This matters for load balancing — you can have VLAN 10 prefer SW1 as root while VLAN 20 prefers SW2.

Verify your current STP mode:

SW1# show spanning-tree summary
Switch is in rapid-pvst mode
Root bridge for: VLAN0010, VLAN0020, VLAN0100
Extended system ID           is enabled
Portfast Default             is disabled
PortFast BPDU Guard Default  is disabled
Portfast BPDU Filter Default is disabled
Loopguard Default            is disabled
PVST Simulation Default      is enabled
Bridge Assurance             is enabled
UplinkFast                   is disabled
BackboneFast                 is disabled
Configured Pathcost method used is short

Name                   Blocking Listening Learning Forwarding STP Active
---------------------- -------- --------- -------- ---------- ----------
VLAN0001                     0         0        0         8          8
VLAN0010                     0         0        0         4          4
VLAN0020                     2         0        0         2          4

Root Bridge Election and Why You Must Control It

The root bridge is elected based on the lowest Bridge ID, which is a combination of bridge priority (default 32768) and the switch’s MAC address. Left to defaults, the switch with the lowest MAC — often the oldest hardware — wins the election. That’s almost never what you want.

In a well-designed campus, your distribution or core switches should be the root. Configure this explicitly:

! Set SW1 as primary root for VLAN 10
SW1(config)# spanning-tree vlan 10 priority 0

! Or use the macro (sets to 24576 for primary, 28672 for secondary)
SW1(config)# spanning-tree vlan 10 root primary
SW1(config)# spanning-tree vlan 20 root secondary

! Verify root placement
SW1# show spanning-tree vlan 10

VLAN0010
  Spanning tree enabled protocol rstp
  Root ID    Priority    10
             Address     0042.5e1a.2b30
             This bridge is the root
             Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec

  Bridge ID  Priority    10     (priority 0 sys-id-ext 10)
             Address     0042.5e1a.2b30
             Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
             Aging Time  300 sec

Interface           Role Sts Cost      Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
Gi1/0/1             Desg FWD 4         128.1    P2p
Gi1/0/2             Desg FWD 4         128.2    P2p
Gi1/0/3             Desg FWD 4         128.3    P2p

Notice the bridge priority shows as 10 with sys-id-ext 10 — IOS-XE automatically adds the VLAN ID to the configured priority. So priority 0 for VLAN 10 becomes an effective Bridge ID priority of 10.

Understanding Port Roles and States

Every STP port has a role and a state. Confusing these two is a common source of diagnostic errors.

Port Roles:

  • Root Port (RP): Best path toward the root bridge. One per non-root switch per VLAN.
  • Designated Port (Desg): Best port on a segment for forwarding toward the root. Every segment has exactly one.
  • Alternate Port (Altn): RSTP backup to the root port — blocked but ready to take over instantly.
  • Backup Port (Back): Redundant designated port on the same segment (rare, usually hub-connected scenarios).

Port States (RSTP): Discarding → Learning → Forwarding. Unlike classic STP, RSTP eliminates Listening entirely.

SW2# show spanning-tree vlan 10 detail

 VLAN0010 is executing the rstp compatible Spanning Tree protocol
  Bridge Identifier has priority 32768, sysid 10, address 0042.5e1a.3c41
  Configured hello time 2, max age 20, forward delay 15, transmit hold-count 6
  We are not the root of the spanning tree
  Topology change flag not set, detected flag not set
  Number of topology changes 3 last change occurred 04:12:38 ago
          from GigabitEthernet1/0/1
  Times:  hold 1, topology change 35, notification 2
          hello 2, max age 20, forward delay 15
  Timers: hello 0, topology change 0, notification 0, aging 300

 Port 1 (GigabitEthernet1/0/1) of VLAN0010 is root forwarding
   Port path cost 4, Port priority 128, Port Identifier 128.1.
   Designated root has priority 10, address 0042.5e1a.2b30
   Designated bridge has priority 10, address 0042.5e1a.2b30
   Designated port id is 128.1, designated path cost 0
   Timers: message age 1, forward delay 0, hold 0
   Number of transitions to forwarding state: 1
   Link type is point-to-point by default
   RSTP information driven to neighbor
   BPDU: sent 7436, received 21847

 Port 2 (GigabitEthernet1/0/2) of VLAN0010 is alternate discarding
   Port path cost 4, Port priority 128, Port Identifier 128.2.
   Designated root has priority 10, address 0042.5e1a.2b30
   Designated bridge has priority 10, address 0042.5e1a.3c55
   Designated path cost 0
   Timers: message age 1, forward delay 0, hold 0
   Number of transitions to forwarding state: 1
   Link type is point-to-point by default
   RSTP information driven to neighbor
   BPDU: sent 3, received 14293

PortFast and BPDU Guard: The Access Layer Essentials

PortFast skips the listening and learning states on access ports connected to end devices — the port goes directly to forwarding. Without it, a workstation or IP phone waits 30 seconds before it can communicate, which is noticeable and causes complaints.

But PortFast on a port that connects to another switch is catastrophic — you’ll briefly create a loop before STP recovers. This is where BPDU Guard comes in: if a PortFast-enabled port receives any BPDU (which only switches send), it immediately err-disables the port.

! Enable PortFast on access port
SW1(config)# interface GigabitEthernet1/0/24
SW1(config-if)# spanning-tree portfast

! Enable BPDU Guard globally on all PortFast ports (recommended)
SW1(config)# spanning-tree portfast bpduguard default

! Or per-interface
SW1(config-if)# spanning-tree bpduguard enable

! Verify
SW1# show spanning-tree interface gi1/0/24 detail

 Port 24 (GigabitEthernet1/0/24) of VLAN0010 is designated forwarding
   Port path cost 4, Port priority 128, Port Identifier 128.24.
   ...
   The port is in the portfast mode by portfast configuration
   Bpdu guard is enabled

When BPDU Guard fires:

%SPANTREE-2-BLOCK_BPDUGUARD: Received BPDU on port GigabitEthernet1/0/24 with
BPDU Guard enabled. Disabling port.
%PM-4-ERR_DISABLE: bpduguard error detected on Gi1/0/24, putting Gi1/0/24 in
err-disable state

SW1# show interfaces gi1/0/24 status
Port      Name               Status       Vlan       Duplex  Speed Type
Gi1/0/24                     err-disabled 10         auto    auto  10/100/1000BaseTX

Recover the port after removing the rogue switch:

SW1(config)# interface GigabitEthernet1/0/24
SW1(config-if)# shutdown
SW1(config-if)# no shutdown

Configure auto-recovery for less critical environments:

SW1(config)# errdisable recovery cause bpduguard
SW1(config)# errdisable recovery interval 300

BPDU Filter: Use With Caution

BPDU Filter stops BPDUs from being sent or received on a port. Unlike BPDU Guard, it doesn’t err-disable — it just silently disables STP on that interface. This is appropriate on provider-facing ports where you genuinely don’t want to participate in the customer’s STP, but dangerous on internal ports. If configured globally, PortFast ports that receive BPDUs lose their filter and behave normally — this is the safe mode. Per-interface BPDU Filter is permanent and bypasses this safety mechanism.

! Global mode (safer - reverts to normal STP if BPDUs received)
SW1(config)# spanning-tree portfast bpdufilter default

! Per-interface (use only on known edge/uplink ports facing SP)
SW1(config-if)# spanning-tree bpdufilter enable

Root Guard and Loop Guard

Root Guard prevents a port from becoming a root port, protecting against rogue switches claiming the root role. Deploy it on ports facing access-layer switches or customer equipment — any port where an unauthorized root bridge could appear.

! Enable Root Guard on distribution downlinks
SW1(config)# interface range GigabitEthernet1/0/1-8
SW1(config-if-range)# spanning-tree guard root

! If a superior BPDU arrives, the port goes to root-inconsistent state
%SPANTREE-2-ROOTGUARD_BLOCK: Root guard blocking port GigabitEthernet1/0/5 on
VLAN0010.

SW1# show spanning-tree inconsistentports
Name                  Interface              Inconsistency
--------------------- ---------------------- ------------------
VLAN0010              GigabitEthernet1/0/5   Root Inconsistent

Number of inconsistent ports (segments) in the system : 1

Loop Guard protects against unidirectional link failures — a scenario where BPDUs stop being received on a port but the link remains physically up (common with fiber). Without Loop Guard, the port transitions to forwarding and creates a loop. With Loop Guard, it enters loop-inconsistent state instead.

! Enable globally (recommended on all non-edge ports)
SW1(config)# spanning-tree loopguard default

! Verify loop-inconsistent ports
SW1# show spanning-tree inconsistentports

Note: Root Guard and Loop Guard are mutually exclusive on the same interface — Root Guard takes precedence.

Diagnosing Topology Changes

Excessive Topology Change Notifications (TCNs) are a major STP issue that causes MAC address table flushes and performance degradation. The symptom is periodic unicast flooding across the network.

! Check topology change statistics
SW1# show spanning-tree vlan 10 detail | include topology

  Number of topology changes 847 last change occurred 00:02:14 ago
          from GigabitEthernet1/0/23

847 topology changes is a red flag. The source port (Gi1/0/23) is the culprit. Check what’s connected there — a port flapping, a hub, or a VoIP phone with a PC behind it can all generate excessive TCNs.

! See current STP state across all VLANs
SW1# show spanning-tree summary totals

 Switch is in rapid-pvst mode
 Root bridge for: VLAN0001 VLAN0010 VLAN0020
                                                    Topology
Name          Blocking Listening Learning Forwarding Changes
------------- -------- --------- -------- ---------- -------
Total             4        0        0       124       1247

For per-VLAN topology change tracking, the Cisco EEM scripting guide covers how to create event triggers that log and alert when STP topology changes exceed a threshold — invaluable in production environments.

Bridge Assurance

Bridge Assurance is a Cisco enhancement (enabled by default on Catalyst switches) that sends BPDUs on all network ports regardless of state. If a connected switch stops responding, the port moves to inconsistent (blocking) state rather than incorrectly forwarding traffic. This prevents one-way link failures from creating loops on trunk ports.

SW1# show spanning-tree summary | include Bridge

Bridge Assurance             is enabled

! Per-interface verification
SW1# show spanning-tree interface gi1/0/1 detail | include Assurance

   The port is designated spanning tree assurance port
   Link type is point-to-point by default

Bridge Assurance only works on point-to-point (full-duplex) ports. It’s automatically disabled on PortFast ports and shared (half-duplex) links.

STP Path Cost and Port Priority Tuning

When multiple equal-cost paths exist to the root, STP uses port priority (then port ID) as a tiebreaker. You can influence which port becomes the root port or designated port by adjusting these values.

! Lower path cost = preferred path (802.1t long path cost for 10G = 2000)
SW2(config)# interface GigabitEthernet1/0/1
SW2(config-if)# spanning-tree vlan 10 cost 2

! Lower port priority = preferred port (default 128, range 0-240 in multiples of 16)
SW1(config-if)# spanning-tree vlan 10 port-priority 64

! Verify path cost method (long = supports 10G and higher)
SW1(config)# spanning-tree pathcost method long

SW1# show spanning-tree vlan 10 interface gi1/0/1

Vlan                Role Sts Cost      Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
VLAN0010            Desg FWD 2         64.1     P2p

MST: When PVST+ Becomes a Scaling Problem

Rapid PVST+ runs one STP instance per VLAN. With 200+ VLANs, this means 200+ STP instances consuming CPU and bandwidth. Multiple Spanning Tree (802.1s) maps multiple VLANs to fewer STP instances — typically 2-4 — dramatically reducing overhead while preserving load-balancing capability.

SW1(config)# spanning-tree mode mst

SW1(config)# spanning-tree mst configuration
SW1(config-mst)# name REGION1
SW1(config-mst)# revision 1
SW1(config-mst)# instance 1 vlan 1-100
SW1(config-mst)# instance 2 vlan 101-200
SW1(config-mst)# show current

Current MST configuration
Name      [REGION1]
Revision  1    Instances configured 3

Instance  Vlans mapped
--------  ---------------------------------------------------------------------
0         201-4094
1         1-100
2         101-200

SW1(config)# spanning-tree mst 1 root primary
SW1(config)# spanning-tree mst 2 root secondary

All switches in the MST region must share identical name, revision, and VLAN-to-instance mapping. A mismatch causes the switch to appear as a separate region, which changes topology behavior. Verify with show spanning-tree mst configuration digest and confirm the Configuration Digest matches across all switches.

Practical Troubleshooting Workflow

When you suspect an STP problem, follow this sequence:

  1. Confirm the root bridge: show spanning-tree vlan X | include root — verify it’s where you expect it.
  2. Check for TCN storms: show spanning-tree detail | include topology across switches.
  3. Look for err-disabled ports: show interfaces status err-disabled
  4. Check inconsistent ports: show spanning-tree inconsistentports
  5. Trace the root port path: Follow root ports hop by hop to verify traffic takes the intended path.
  6. Enable STP debug with caution: debug spanning-tree events on a non-production switch, or use EEM logging instead.
! Quick health snapshot across all VLANs
SW1# show spanning-tree summary
SW1# show spanning-tree inconsistentports
SW1# show interfaces status err-disabled

For deeper packet-level analysis, scripting a polling loop across multiple switches with Netmiko is far faster than logging into each box individually during an outage — especially when you’re chasing a topology change across ten access-layer switches at 2 AM.

STP Design Best Practices

The most important STP decision is one you make before configuring anything: keep your Layer 2 domain small. Every switch you add to a VLAN extends the failure domain for that VLAN’s STP instance. Use routed access (Layer 3 to the access layer) wherever possible — eliminate the need for STP entirely in those segments. Where you do need Layer 2, follow these rules:

  • Always configure root bridges explicitly — never leave them to chance.
  • Deploy PortFast + BPDU Guard on every access port, globally.
  • Enable Root Guard on all ports facing access switches.
  • Enable Loop Guard globally on all trunk ports.
  • Use Bridge Assurance (default on Catalyst) on all inter-switch links.
  • Document your STP topology and validate it matches reality after every change.
  • Consider MST if you’re running more than 50 VLANs on a significant number of switches.

The relationship between STP and VLANs is covered in depth in the VLANs and network segmentation guide — worth reviewing if you’re designing a new campus or troubleshooting VLAN-specific forwarding issues.

Final Thoughts

Spanning tree is one of those protocols that works invisibly when configured correctly and catastrophically when it isn’t. The fact that it’s been around since 1985 doesn’t mean it’s simple — the interactions between root guard, loop guard, bridge assurance, and port roles catch engineers off guard regularly. Get comfortable reading show spanning-tree detail output until it’s second nature. Know where your root bridges are. Deploy PortFast and BPDU Guard everywhere appropriate, without exception. And always, always configure root bridge priority explicitly — never trust a production network to elect it automatically.

For environments where you’re also managing Cisco routing protocols, the OSPF troubleshooting guide pairs well with this — many campus network issues involve both Layer 2 STP instability and Layer 3 routing impacts.

Enjoying this post?

Get more guides like this delivered straight to your inbox. No spam, just tech and trails.