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:
- Confirm the root bridge:
show spanning-tree vlan X | include root— verify it’s where you expect it. - Check for TCN storms:
show spanning-tree detail | include topologyacross switches. - Look for err-disabled ports:
show interfaces status err-disabled - Check inconsistent ports:
show spanning-tree inconsistentports - Trace the root port path: Follow root ports hop by hop to verify traffic takes the intended path.
- Enable STP debug with caution:
debug spanning-tree eventson 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.
Leave a Reply