Mental model
Spanning Tree’s correctness depends on every switch agreeing on a single root bridge and stable port roles. Two ways this gets broken:
Someone plugs a switch into a user-facing access port. The new switch sends BPDUs. STP recalculates. Topology destabilizes. Sometimes the new switch even wins the root election if its bridge ID happens to be lower — now traffic flows through some random switch in a meeting room.
A downstream switch tries to become root. Whether by accident (someone hardcoded a low priority) or attack (someone trying to force traffic through their device), an unexpected switch claiming root status can hijack your topology.
BPDU Guard fixes #1. Root Guard fixes #2. Both are essential in production switching environments.
BPDU Guard — protect access ports
The premise: PCs, printers, IP phones, IoT — none of them send BPDUs. So if a port that should connect only to end devices ever receives a BPDU, something is wrong. Maybe someone connected a switch. Maybe a misconfigured device. Either way, the safe response is to shut the port.
BPDU Guard does exactly that: any BPDU on a protected port → err-disable the port immediately.
Where it goes
On every access port that has PortFast enabled:
SW1(config-if)# switchport mode access
SW1(config-if)# spanning-tree portfast ! skip listening/learning
SW1(config-if)# spanning-tree bpduguard enable ! shut on BPDU
PortFast + BPDU Guard is the standard combo. PortFast skips STP states for instant forwarding on access ports; BPDU Guard catches anyone abusing that.
Global default
You can enable both globally so every PortFast port automatically gets BPDU Guard:
SW1(config)# spanning-tree portfast bpduguard default
SW1(config)# spanning-tree portfast default
Now every access port with PortFast also has BPDU Guard, automatically. Best practice.
Root Guard — pin the root bridge
The premise: you’ve deliberately chosen a root bridge (e.g. a core switch with spanning-tree vlan 1 root primary). You don’t want some downstream switch — a closet switch, a user-deployed device — claiming better priority and becoming root.
Root Guard protects this by inspecting BPDUs arriving on a designated port. If an incoming BPDU is “superior” (better priority than the current root’s), Root Guard blocks the port rather than letting it influence root election.
The port enters a special root-inconsistent state. Once the superior BPDUs stop arriving, the port recovers automatically (no manual intervention).
Where it goes
On ports facing downstream switches — switches that should never be root:
SW1(config)# interface GigabitEthernet0/24
SW1(config-if)# spanning-tree guard root
That’s it. The port now refuses to let anything “better” through it.
When it kicks in
*Mar 1 12:34:56: STP: VLAN0010 Gi0/24 received superior BPDU, blocked by root guard
*Mar 1 12:35:01: STP: VLAN0010 Gi0/24 root guard inconsistent (no superior BPDUs for 30s, recovering)
First message: blocked. Second message: superior BPDUs stopped, port recovers automatically.
When to use each
| Port type | BPDU Guard | Root Guard |
|---|---|---|
| Access port (PCs, phones, IoT) | ✓ | ✗ |
| Trunk to downstream switch (closet, distribution) | ✗ | ✓ |
| Trunk to upstream switch (where root might be) | ✗ | ✗ |
BPDU Guard is binary — no BPDUs allowed here at all. Use on access ports.
Root Guard is conditional — BPDUs OK, but they better not be better than the current root. Use on downstream-facing trunks.
BPDU Filter — the dangerous cousin
There’s also BPDU Filter, which silently drops BPDUs without err-disabling. It sounds safer but it’s not — it lets a connected switch operate as if it’s a loop-free endpoint, which can cause real loops if the connection forms a loop.
BPDU Filter is dangerous. Avoid it. BPDU Guard is the right tool.
! NEVER do this on access ports
SW1(config-if)# spanning-tree bpdufilter enable ! silent drop — DON'T
The one legitimate use of BPDU Filter: on ports that genuinely need to never send/receive BPDUs (rare service-provider edge cases). For 99% of CCNA-level networks, don’t.
Recovery from err-disable
BPDU Guard puts the port in err-disable. Recovery options:
Manual
SW1(config)# interface Gi0/5
SW1(config-if)# shutdown
SW1(config-if)# no shutdown
Auto-recovery
SW1(config)# errdisable recovery cause bpduguard
SW1(config)# errdisable recovery interval 300 ! 5 minutes
After 5 minutes, the port comes back up automatically. If the offending BPDUs are still arriving, it shuts again. Cycles until someone investigates.
Common mistakes
PortFast on a trunk port. PortFast is for access ports only. A trunk in PortFast mode is a loop waiting to happen. The default config prevents this on Catalyst, but mis-applied
spanning-tree portfast trunkon a real trunk = bad.BPDU Guard without PortFast. Pointless — non-PortFast access ports go through listening/learning anyway, so a BPDU during that time is normal. Together they form the bundle.
Root Guard on an upstream port facing the actual root. Now your switch refuses to learn the legitimate root. Catastrophic. Apply Root Guard only on downstream ports.
Forgetting err-disable recovery. A momentary BPDU arrival → port permanently down until someone notices. Configure recovery (with caution — don’t auto-recover if the cause is unclear).
Confusing BPDU Guard and BPDU Filter. BPDU Guard shuts on BPDU. BPDU Filter silently drops. Guard is safe; Filter is dangerous. Test before deploying either.
No documentation. When the port flaps to err-disable at 3 AM, the on-call engineer needs to know “this is BPDU Guard — someone connected an unauthorized switch.” Document the policy.
Lab to try tonight
- One switch, two PCs on access ports, plus a spare switch for testing.
- Configure PortFast + BPDU Guard on the access ports:
interface range Gi0/1 - 24
switchport mode access
spanning-tree portfast
spanning-tree bpduguard enable
- Plug PC into Gi0/1. Verify it works.
- Replace PC with the spare switch. Watch Gi0/1 err-disable as soon as the spare switch sends a BPDU.
- Confirm:
show interfaces status err-disabledand the logs. - Restore:
shutthenno shut. Or configureerrdisable recovery cause bpduguard. - Now apply Root Guard on a trunk:
spanning-tree guard root. - From the downstream switch, force a low bridge priority that would otherwise win root election. Verify Root Guard blocks the port and logs
root guard inconsistent.
Cheat strip
| Concept | Plain English |
|---|---|
| BPDU Guard | Access port + PortFast — err-disable on any BPDU |
| Root Guard | Downstream trunk — block port if superior BPDU arrives |
| BPDU Filter | Silently drop BPDUs. Dangerous — avoid. |
| PortFast | Skip STP listening/learning — instant forwarding on access ports |
spanning-tree portfast bpduguard default | Global — enable both on all PortFast ports |
spanning-tree guard root | Per-interface — block port if it would change root |
| err-disable recovery | Auto-recover after N seconds |
| root-inconsistent | Special Root Guard state — recovers when superior BPDUs stop |
