Spanning Tree Protocol (STP) and RSTP on Cisco IOS-XE: Configuration, Troubleshooting, and Best Practices

If you’ve ever watched a network loop bring down a whole campus in seconds, you understand why Spanning Tree Protocol exists. STP is one of those foundational technologies that every network engineer needs to know cold — not just the theory, but the CLI, the timers, the failure modes, and the troubleshooting workflow. This guide covers STP and its faster successor RSTP (Rapid Spanning Tree Protocol) on Cisco IOS-XE, with real command output and practical configuration examples you can use in production.

Why STP Exists: The Layer 2 Loop Problem

Ethernet switches forward frames based on MAC address tables. When a frame arrives with an unknown destination, a switch floods it out every port except the one it arrived on. In a network with redundant links and no loop prevention, that flood becomes infinite. Every switch re-floods every copy, until bandwidth is saturated and the network collapses. This is a broadcast storm, and it can take down an enterprise network in under a minute.

STP solves this by creating a loop-free logical topology from a physically redundant network. It elects one switch as the root bridge, then blocks redundant paths — keeping them available for failover while preventing loops during normal operation. Understanding how VLANs interact with STP is essential, because in Cisco’s Per-VLAN STP+ (PVST+), each VLAN runs its own independent STP instance.

STP 802.1D: The Basics

Classic STP (IEEE 802.1D) uses the following process to build a loop-free topology:

  1. Root bridge election: The switch with the lowest Bridge ID wins. Bridge ID = Priority (default 32768) + System ID Extension (VLAN ID in PVST+) + MAC address as tiebreaker.
  2. Root port selection: Every non-root switch picks the port with the lowest cost path to the root.
  3. Designated port selection: On each network segment, one port is elected designated — it forwards traffic toward that segment on behalf of the root.
  4. Port blocking: All remaining ports are put in Blocking state to eliminate loops.

The main pain point with 802.1D is convergence time. Ports transition through Blocking → Listening → Learning → Forwarding, with 15-second timers at Listening and Learning by default. Total convergence after a topology change: up to 50 seconds. That’s unacceptable in modern networks.

RSTP 802.1w: Faster Convergence

Rapid Spanning Tree Protocol (IEEE 802.1w) reduces convergence to sub-second in most topologies by introducing new port roles and states:

  • Port roles: Root, Designated, Alternate (replaces Blocking), Backup
  • Port states: Discarding, Learning, Forwarding (collapsed from STP’s five states)
  • Proposal/Agreement mechanism: Instead of waiting for timers, RSTP switches negotiate directly to move ports to Forwarding instantly on point-to-point links
  • Edge ports: Ports connected to end devices skip the negotiation entirely and go directly to Forwarding (PortFast equivalent)

On Cisco IOS-XE, the default mode is Rapid-PVST+, which runs an RSTP instance per VLAN. This is what you should be running in production unless you have a specific reason for 802.1s (MST).

Verifying Your STP Mode

Before making any changes, verify what’s running:

SW1# show spanning-tree summary
Switch is in rapid-pvst mode
Root bridge for: VLAN0001, VLAN0010, VLAN0020, VLAN0100

Name                   Blocking Listening Learning Forwarding STP Active
---------------------- -------- --------- -------- ---------- ----------
VLAN0001                     0         0        0          8          8
VLAN0010                     0         0        0          6          6
VLAN0020                     1         0        0          5          6
VLAN0100                     0         0        0          4          4
---------------------- -------- --------- -------- ---------- ----------
4 vlans                      1         0        0         23         24

If you see pvst mode instead of rapid-pvst mode, you’re running legacy STP. Upgrade with:

SW1(config)# spanning-tree mode rapid-pvst

Root Bridge Placement: Don’t Leave It to Chance

A common mistake is letting STP elect the root bridge based on the lowest MAC address. The switch that wins might be an access layer switch, creating suboptimal traffic paths. Always explicitly configure your distribution or core switches as root.

Method 1: Macro command (recommended)

SW-DIST1(config)# spanning-tree vlan 1,10,20,100 root primary
SW-DIST2(config)# spanning-tree vlan 1,10,20,100 root secondary

The root primary macro sets priority to 24576 (if the current root has default priority) or lower. The root secondary macro sets priority to 28672.

Method 2: Manual priority

SW-DIST1(config)# spanning-tree vlan 10 priority 4096
SW-DIST2(config)# spanning-tree vlan 10 priority 8192

Priority must be a multiple of 4096. Lower = better. Verify after:

SW-DIST1# show spanning-tree vlan 10

VLAN0010
  Spanning tree enabled protocol rstp
  Root ID    Priority    4106
             Address     0c1b.5400.0001
             This bridge is the root
             Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec

  Bridge ID  Priority    4106   (priority 4096 sys-id-ext 10)
             Address     0c1b.5400.0001
             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
Gi1/0/4             Desg FWD 19        128.4    P2p

The This bridge is the root line confirms correct placement. Note the priority shown (4106) is 4096 + 10 (VLAN ID extension).

STP Port Cost

Root port selection uses path cost. IOS-XE uses long-mode costs by default on modern switches (Cat9K):

Link Speed Short-mode Cost Long-mode Cost
10 Mbps 100 2,000,000
100 Mbps 19 200,000
1 Gbps 4 20,000
10 Gbps 2 2,000
100 Gbps 1 200

Check which mode your switch uses:

SW1# show spanning-tree pathcost method
Spanning tree default pathcost method used is long

To influence which uplink a switch prefers, manually lower the port cost on the preferred link:

SW1(config)# interface GigabitEthernet1/0/1
SW1(config-if)# spanning-tree vlan 10 cost 10000

Critical STP Features: PortFast, BPDU Guard, and Root Guard

These three features are non-negotiable in a well-configured network. If you’re not running them on access ports, you’re one rogue switch away from a spanning tree disaster.

PortFast

PortFast skips the Listening and Learning states on access ports connected to end devices. The port goes directly to Forwarding. This eliminates the 30-second delay that users experience when plugging in a laptop.

SW1(config)# interface range GigabitEthernet1/0/1 - 24
SW1(config-if-range)# spanning-tree portfast

Or enable globally for all access ports (recommended):

SW1(config)# spanning-tree portfast default

Important: PortFast should only be on ports connected to end devices, never on trunk ports to other switches.

BPDU Guard

BPDU Guard shuts down a PortFast-enabled port if it receives a BPDU. This prevents someone from plugging in an unmanaged switch or a device running STP and disrupting your topology.

SW1(config)# spanning-tree portfast bpduguard default

When triggered, the port goes into err-disabled state:

SW1# show interfaces GigabitEthernet1/0/5 status
Port      Name               Status       Vlan       Duplex  Speed Type
Gi1/0/5                      err-disabled 10         auto    auto  10/100/1000BaseTX
SW1# show errdisable recovery
ErrDisable Reason            Timer Status
-----------------            --------------
bpduguard                    Enabled (300 seconds)

To auto-recover after 5 minutes instead of manual intervention:

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

Root Guard

Root Guard prevents a port from becoming a root port. If a superior BPDU is received on a Root Guard-enabled port, the port is placed into root-inconsistent state. Apply it on designated ports facing access layer switches where a root bridge should never appear.

SW-DIST1(config)# interface GigabitEthernet1/0/10
SW-DIST1(config-if)# spanning-tree guard root

Verify with:

SW-DIST1# show spanning-tree inconsistentports

Name                 Interface              Inconsistency
-------------------- ---------------------- ------------------
VLAN0010             GigabitEthernet1/0/10  Root Inconsistent

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

BPDU Filter: Use With Caution

BPDU Filter prevents a port from sending or receiving BPDUs. When applied globally (spanning-tree portfast bpdufilter default), it only suppresses BPDUs on PortFast ports — if a BPDU is received, the port loses PortFast status and participates in STP normally. Safe.

When applied per-interface (spanning-tree bpdufilter enable), BPDUs are completely ignored in both directions. This effectively disables STP on that port and can create loops if misconfigured. Only use per-interface BPDU Filter in specific scenarios like provider edge connections.

Troubleshooting STP: The Essential Commands

Here’s the core troubleshooting workflow Sarah runs when a ticket comes in for an STP issue:

Step 1: Identify the root bridge

SW1# show spanning-tree vlan 10 | include Root ID|This bridge|Address
  Root ID    Priority    4106
             Address     0c1b.5400.0001
             This bridge is the root

If “This bridge is the root” doesn’t appear, find it:

SW1# show spanning-tree vlan 10 | include Root ID|Hello|Address
  Root ID    Priority    4106
             Address     0c1b.5400.0001
             Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec

Then find the switch with that MAC address using CDP:

SW1# show cdp neighbors detail | include Device ID|IP address

Step 2: Check port states and roles

SW1# show spanning-tree vlan 10 detail

 VLAN0010 is executing the rstp compatible Spanning Tree protocol
  Bridge Identifier has priority 32778, sysid 10, address f872.ea41.6480
  Configured hello time 2, max age 20, forward delay 15
  Current root has priority 4106, address 0c1b.5400.0001
  Root port is 1 (GigabitEthernet1/0/1), cost of root path is 20000

 GigabitEthernet1/0/1 of VLAN0010 is root forwarding
   Port info             port id 128.1 priority 128 cost 20000
   Designated root       has priority 4106, address 0c1b.5400.0001
   Designated bridge     has priority 4106, address 0c1b.5400.0001
   Designated port id is 128.3, 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, Peer is STP
   BPDU: sent 0, received 14523

Step 3: Watch for topology changes

SW1# show spanning-tree vlan 10 detail | include topology|TCN|changes
  Number of topology changes 12 last change occurred 0:04:32 ago
  from GigabitEthernet1/0/3

Frequent topology changes flush MAC tables, increasing flooding and CPU load. If you see high TC counts, the port shown is worth investigating. Common causes: a flapping access port, a PortFast port receiving BPDUs, or a misbehaving NIC.

Step 4: Look for blocking ports

SW1# show spanning-tree blockedports

Name                 Blocked Interfaces List
-------------------- ------------------------------------
VLAN0020             GigabitEthernet1/0/4

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

A blocked port is expected in a redundant topology — it’s STP working correctly. The concern is if a port that should be forwarding is blocked, or if a formerly blocked port won’t come up after a failure.

Step 5: STP debugging (use sparingly in production)

SW1# debug spanning-tree events
Spanning Tree event debugging is on

SW1#
*May 15 08:23:11.442: STP: VLAN0010 we are the spanning tree root
*May 15 08:23:11.447: STP: VLAN0010 Gi1/0/4 -> listening
*May 15 08:23:26.448: STP: VLAN0010 Gi1/0/4 -> learning
*May 15 08:23:41.448: STP: VLAN0010 Gi1/0/4 -> forwarding

Always disable debug after use: undebug all

Common STP Issues and Fixes

Issue: Suboptimal root bridge placement

Symptom: Traffic takes a circuitous path through the network, high-latency inter-VLAN routing.
Fix: Explicitly configure priority on distribution switches. Use show spanning-tree vlan X root on all switches to map the topology.

Issue: Unidirectional link causing loop

Symptom: A port is Forwarding on both ends but one side can’t receive BPDUs — the port that should be blocking stays Forwarding.
Fix: Enable UDLD (Unidirectional Link Detection):

SW1(config)# udld enable
SW1(config)# interface GigabitEthernet1/0/1
SW1(config-if)# udld port aggressive

Issue: Slow convergence on trunk ports

Symptom: Trunk port takes 30+ seconds to come up after link recovery.
Fix: Ensure trunk ports are NOT configured with PortFast. They should participate in full RSTP negotiation. Verify with show spanning-tree interface Gi1/0/1 detail and check the Link type line shows point-to-point for P2P RSTP convergence.

Issue: STP loop on access layer

Symptom: Broadcast storm, high CPU on switches, users losing connectivity.
Fix: Identify source with show spanning-tree detail | include from. Enable Loop Guard on non-edge ports:

SW1(config)# spanning-tree loopguard default

Loop Guard puts a port into loop-inconsistent state instead of Forwarding if BPDUs stop arriving, preventing the port from incorrectly becoming designated.

STP and Cisco Catalyst 9000 (Cat9K) Specifics

If you’re managing Cat9K switches, a few things to know. The hardware supports hardware-accelerated spanning tree on some platforms, which means the software STP decisions are offloaded. You can verify the STP hardware mode:

SW1# show platform spanning-tree summary

Global STP HW mode: Hardware-Accelerated mode

Also, Cat9K running IOS-XE 17.x defaults to long STP path cost method. If you’re migrating from older IOS where short was default, this can change port roles and cause unexpected topology changes. Check the mode before upgrading and explicitly set it to avoid surprises:

SW1(config)# spanning-tree pathcost method long

For more on IOS-XE platform differences, see our Cisco IOS vs IOS-XE vs IOS-XR comparison.

STP Best Practices Checklist

  • Run Rapid-PVST+ (spanning-tree mode rapid-pvst) on all switches
  • Explicitly set root bridge priority on distribution/core — never leave it to MAC address election
  • Enable PortFast on all access ports, with BPDU Guard enabled globally
  • Apply Root Guard on distribution ports facing access layer switches
  • Enable Loop Guard globally (spanning-tree loopguard default)
  • Enable UDLD on all fiber uplinks
  • Document your intended root bridges and blocked ports — know what “normal” looks like
  • Monitor TC (Topology Change) counts; more than a few per hour warrants investigation
  • Use MST (802.1s) if you have hundreds of VLANs to reduce STP instance overhead

STP troubleshooting follows the same disciplined approach as OSPF troubleshooting — start from what you know (root bridge, expected port roles), verify against reality, and narrow down systematically from there.

Wrapping Up

STP and RSTP are old protocols, but they’re absolutely not obsolete. As long as Ethernet switches exist in Layer 2 domains, loop prevention is mandatory. The difference between a network that handles a link failure gracefully and one that collapses in a broadcast storm often comes down to whether someone took the time to configure root bridge placement, BPDU Guard, and Loop Guard properly.

The commands in this guide — from show spanning-tree summary to watching topology change counts — should be part of every network engineer’s muscle memory. Run them regularly, know what your baseline looks like, and you’ll catch STP anomalies before they become incidents.

Enjoying this post?

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