If you’ve ever managed a Cisco Catalyst 9000 series switch in production, you know that IOS-XE software upgrades are one of those tasks that look simple on paper but can take down a core switch if you get them wrong. Bundle mode vs. install mode, ISSU eligibility, pre-upgrade verifications, and the dreaded rommon> prompt — there’s a lot to navigate. This guide walks through the complete upgrade process with real IOS-XE commands and common failure scenarios so you don’t have to learn the hard way.
Bundle Mode vs. Install Mode: Know the Difference
Before anything else, you need to know which mode your switch is running. The Catalyst 9000 series supports two software packaging modes:
- Bundle mode: The switch boots from a single monolithic
.binfile. Simpler, but requires a full reload on every upgrade — no ISSU support. - Install mode: The switch boots from sub-packages extracted to flash. Supports In-Service Software Upgrade (ISSU) on supported hardware, and allows rollback. This is the recommended mode for production.
Check which mode you’re running with show install summary:
SW1# show install summary
[ Switch 1 ] Installed Package(s) Information:
State (St): I - Inactive, U - Activated & Uncommitted,
C - Activated & Committed, D - Deactivated & Uncommitted
--------------------------------------------------------------------------------
Type St Filename/Version
--------------------------------------------------------------------------------
IMG C 17.09.04a.0.4
--------------------------------------------------------------------------------
Auto abort timer: inactive
Or check the boot statement:
SW1# show running-config | include boot system
boot system flash:packages.conf
If you see packages.conf, you’re in install mode. If you see a full .bin filename like cat9k_iosxe.17.09.04a.SPA.bin, you’re in bundle mode. For production Cat9K deployments, install mode is strongly preferred. Converting between modes requires a full reload with the new boot statement — plan a maintenance window if you’re making this switch.
Pre-Upgrade Checklist
Rushing an upgrade without pre-checks is how you end up in rommon. Run through this list before touching the software.
1. Verify Current Software and Hardware
SW1# show version
Cisco IOS XE Software, Version 17.09.04a
...
Cisco Catalyst 9300-48P
...
SW1 uptime is 312 days, 4 hours, 12 minutes
SW1# show inventory
NAME: "Switch 1" , DESCR: "C9300-48P"
PID: C9300-48P , VID: V02 , SN: FCW2345A0BC
Cross-reference the PID and VID against the Cisco Software Compatibility Matrix. Not all hardware VIDs support all software versions — catching this before you start saves a lot of pain.
2. Check Available Flash Space
SW1# dir flash: | include bytes
24006172672 bytes total (13421772800 bytes free)
SW1# show file systems
Size(b) Free(b) Type Flags Prefixes
- - opaque rw system:
- - opaque rw tmpsys:
24006172672 13421772800 disk rw flash: harddisk: flash0:
IOS-XE 17.x images for Cat9K typically require 1.5–2 GB of flash free for install mode. If you’re tight on space, clean up old packages first:
SW1# request platform software package clean switch all
Cleaning up unnecessary package files
No path specified, will use booted path flash:packages.conf
Cleaning flash:
Scanning flash:.....
Found .bin file: flash:cat9k_iosxe.17.06.05.SPA.bin
THIS WILL REMOVE THE FOLLOWING FILES:
flash:cat9k_iosxe.17.06.05.SPA.bin
Do you want to proceed? [y/n]y
Warning: package clean removes inactive packages. Only run this after confirming the current installed version is stable and you have no plans to roll back to an earlier release.
3. Verify Stacking/StackWise Health (If Applicable)
SW1# show switch
Switch/Stack Mac Address : 6c41.0e1a.2b80 - Local Mac Address
Mac persistency wait time: Indefinite
H/W Current
Switch# Role Mac Address Priority Version State
--------------------------------------------------------
*1 Active 6c41.0e1a.2b80 15 V02 Ready
2 Member 6c41.0e1a.5c20 10 V02 Ready
3 Standby 6c41.0e1a.8d40 1 V02 Ready
All stack members must be in Ready state before you start. A stack member in “Provisioned” or “Removed” state will cause problems during upgrade. Also confirm all members are running identical software:
SW1# show switch detail | include SW_VER
SW_VER: 17.09.04a
SW_VER: 17.09.04a
SW_VER: 17.09.04a
Mixed versions in a stack before upgrade is a red flag — investigate and normalize before proceeding.
4. Capture a Pre-Upgrade Baseline
Document the current state so you have a comparison point after upgrade:
SW1# show ip ospf neighbor
SW1# show bgp summary
SW1# show interfaces status | include connected
SW1# show environment all
Save this output. If something behaves differently post-upgrade, you’ll want this reference. For diagnosing routing issues that surface post-upgrade, our OSPF troubleshooting guide covers adjacency failures and flapping in detail.
Copying the New Image to Flash
Download the target IOS-XE image from Cisco’s software portal (requires a valid SmartNet or software contract). Copy it directly to flash via TFTP or HTTP:
SW1# copy tftp://10.0.1.50/cat9k_iosxe.17.12.04.SPA.bin flash:
Destination filename [cat9k_iosxe.17.12.04.SPA.bin]?
Accessing tftp://10.0.1.50/cat9k_iosxe.17.12.04.SPA.bin...
Loading cat9k_iosxe.17.12.04.SPA.bin from 10.0.1.50 (via GigabitEthernet0/0):
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
[OK - 1,016,285,440 bytes]
After the copy completes, verify the MD5 hash against what’s published on Cisco’s download page:
SW1# verify /md5 flash:cat9k_iosxe.17.12.04.SPA.bin
..........Done!
verify /md5 (flash:cat9k_iosxe.17.12.04.SPA.bin) = a3f8b2c197d4e8f620a1b3c9d7e4f201
A hash mismatch means a corrupt download. Re-copy before proceeding — never install a file with a bad hash.
Install Mode Upgrade: The Full Process
The install add / install activate / install commit workflow gives you a controlled, rollback-capable upgrade path. This is the recommended procedure for Cat9K in install mode.
Step 1: Add the New Package
SW1# install add file flash:cat9k_iosxe.17.12.04.SPA.bin activate query
install_add_activate_query: START Sat May 31 03:00:00 UTC 2026
install_add_activate_query: Checking whether new add is allowed ....
--- Starting Add ---
Performing Add on all members
[1] Add package(s) on Switch 1
[2] Add package(s) on Switch 2
[3] Add package(s) on Switch 3
install_add_activate_query: Finished Add
Note the query keyword — this adds the package and checks ISSU eligibility without activating it yet. Review the output carefully. If ISSU is not supported for this upgrade path, you’ll see a warning and the process will require a full reload.
Step 2: Activate (With or Without ISSU)
For ISSU-eligible upgrades:
SW1# install activate issu
install_activate: START Sat May 31 03:05:00 UTC 2026
install_activate: Checking whether new activate is allowed ....
--- Starting ISSU Activate ---
Performing ISSU Activate on all members
[1] Activate packages on Switch 1
[2] Activate packages on Switch 2
[3] Activate packages on Switch 3
--- ISSU in Progress ---
This operation will complete in the background.
For non-ISSU upgrades — schedule a maintenance window, the switch will reload:
SW1# install activate
install_activate: START Sat May 31 03:05:00 UTC 2026
This operation requires a reload of the system. Do you want to proceed? [y/n]y
...
STACK_RELOAD: Sat May 31 03:07:14 UTC 2026
After the reload and reconnection, verify the new software is running:
SW1# show version | include IOS XE Software
Cisco IOS XE Software, Version 17.12.04
Step 3: Commit the Upgrade
This is the step engineers forget. Until you run install commit, a reload will roll the switch back to the previous version. You have a window to test — but don’t leave it uncommitted overnight in production.
SW1# install commit
install_commit: START Sat May 31 03:20:00 UTC 2026
install_commit: Checking whether new commit is allowed ....
--- Starting Commit ---
Performing Commit on all members
[1] Commit packages on Switch 1
[2] Commit packages on Switch 2
[3] Commit packages on Switch 3
--- Done ---
Success: install_commit Sat May 31 03:20:45 UTC 2026
Common Upgrade Gotchas (and How to Avoid Them)
Gotcha 1: Insufficient Flash Space Kills the Install Midway
The install process extracts sub-packages to flash during activation. If flash fills up mid-install, you can end up with a partially extracted image and a switch that won’t boot cleanly. Always verify you have at least 2.5 GB free before starting, not just enough for the .bin file itself.
SW1# show install summary
[ Switch 1 ] Installed Package(s) Information:
...
Type St Filename/Version
IMG C 17.09.04a.0.4
IMG U 17.12.04.0.2
If you see both an active committed version and a newly added uncommitted version, make sure flash has sufficient headroom before activation.
Gotcha 2: Stack Members Don’t All Upgrade
In a StackWise stack, the active switch pushes the new image to all members. If a member has a failing flash or a connection issue during the transfer, it’ll reload on the old image — creating a mixed-version stack. Always check all members post-upgrade:
SW1# show switch detail
Switch Ports Model Serial No. Prio. Version Role State
-----+--------+--------------------+-----------+-----+--------+------+--------+
*1 62 C9300-48P FCW2345A0BC 15 V02 Active Ready
2 62 C9300-48P FCW2345A1CD 10 V02 Standby Ready
3 62 C9300-48P FCW2345A2DE 1 V02 Member Ready
SW1# show switch detail | include SW_VER
If you see version mismatches, the affected member needs to be individually upgraded or removed from the stack and re-added after running the upgrade process against it directly.
Gotcha 3: ISSU Claimed Supported, But Adjacencies Still Dropped
ISSU on Cat9K requires specific conditions: compatible hardware, a StackWise Virtual or stacked configuration, and compatible source/target software versions. Even when ISSU is advertised, some features — certain MPLS LSPs, specific routing protocol configurations — may cause brief traffic interruption during the SSO switchover. Always test in a lab mirroring your production config before assuming ISSU will be hitless in your environment.
SW1# show issu state detail
--- ISSU State ---
Current ISSU Operation : ISSU_INIT
Previous ISSU Operation: NONE
System Check : PASSED
SW1# show redundancy states
my state = 13 -ACTIVE
peer state = 8 -STANDBY HOT
Mode = Duplex
Unit = Primary
Unit ID = 0
Redundancy Mode (Operational) = SSO
Redundancy Mode (Configured) = SSO
Verify SSO is operational — ISSU requires it.
Gotcha 4: Rommon After a Failed Upgrade
If a Cat9K lands in rommon after a failed upgrade, connect via console and boot a known-good image:
switch: dir flash:
switch: boot flash:cat9k_iosxe.17.09.04a.SPA.bin
If the flash image is also corrupted (rare, but it happens), boot from a USB drive with a clean image. Format the USB as FAT32, copy the .bin to it, insert it, and from rommon:
switch: dir usbflash0:
1 1016285440 cat9k_iosxe.17.09.04a.SPA.bin
switch: boot usbflash0:cat9k_iosxe.17.09.04a.SPA.bin
Once back in IOS-XE, run install remove inactive to clean up and start the upgrade process fresh.
Gotcha 5: Licenses Don’t Follow the Software
With Cisco Smart Licensing Using Policy (SLP), license entitlements aren’t embedded in the software — they’re managed through Cisco’s Smart Software Manager (CSSM). After an upgrade, verify your license state:
SW1# show license summary
License Usage:
License Entitlement tag Count Status
-----------------------------------------------------------------------------
network-advantage (C9300-48 Network Advantage) 1 IN USE
dna-advantage (C9300-48 DNA Advantage) 1 IN USE
SW1# show license status | include Status
Status: REGISTERED
If a license shows “OUT OF COMPLIANCE” post-upgrade, check your Smart Account and verify entitlements are properly assigned. This most often surfaces when upgrading from older perpetual licensing to SLP.
Post-Upgrade Verification
Don’t close the maintenance window until you’ve validated the switch is functioning correctly:
SW1# show ip ospf neighbor
Neighbor ID Pri State Dead Time Address Interface
10.0.1.2 1 FULL/DR 00:00:38 10.10.1.2 Vlan100
10.0.1.3 1 FULL/BDR 00:00:34 10.10.1.3 Vlan100
SW1# show bgp summary | include ^Neighbor|Estab
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
10.0.0.1 4 65001 8401 8402 240 0 0 01:05:22 1204
SW1# show interfaces counters errors
SW1# show environment temperature
SW1# show environment power
SW1# show log | include %LINK-3
Pay particular attention to interface error counters — CRC errors or input errors that weren’t there before can indicate a compatibility issue between new software and specific line cards or optics. Also verify that your Control Plane Policing policies survived the upgrade intact; the CoPP guide covers baseline verification commands. If you upgraded across a major release boundary, also check that AAA authentication is still enforcing correctly — TACACS+ and RADIUS behavior can shift between major releases.
Rolling Back If Needed
If you haven’t committed, a reload automatically rolls back. If you have committed but need to go back:
SW1# install rollback to committed
install_rollback: START Sat May 31 04:00:00 UTC 2026
install_rollback: Checking whether new rollback is allowed ....
--- Starting Rollback ---
This operation will reload the system. Do you want to proceed? [y/n]y
Or roll back to a specific version by label:
SW1# show install log
[R0] install_log: SUCCESS install_commit Wed May 28 02:20:00 UTC 2026
[R0] install_log: SUCCESS install_activate Wed May 28 02:00:00 UTC 2026
SW1# install rollback to label "17.09.04a"
Keep in mind: rolling back across major feature releases can break config elements that use syntax or features introduced in the version you’re rolling back from. Always test rollback in a lab if your production config is complex.
Upgrade Version Targeting: Which Release to Run?
Cisco maintains a tiered release train for IOS-XE on Cat9K:
- Extended Maintenance Release (EMR): Long support lifecycle, suitable for production. Cisco recommends targeting the latest EMR for stable deployments (currently 17.09.x and 17.12.x as of 2026).
- Short-lived (SL): Includes new features but a shorter support window. Good for testing new capabilities, not for long-term production.
- Standard Maintenance Release (SMR): Moderate feature inclusion, reasonable support lifecycle.
For most production environments, run the latest maintenance release within the current EMR train. Avoid bleeding-edge SL releases unless you specifically need a feature they introduce.
SW1# show version | include Compiled
Compiled Thu 15-Feb-24 02:43 by mcpre
Read the release notes for your target version — specifically the “Caveats” section. Known bugs with workarounds are called out there. Some Cat9K caveats have triggered spontaneous reloads, STP topology changes, or OSPF adjacency flaps immediately post-upgrade. Release notes are not optional reading.
Upgrade Automation with EEM and Python
For environments with many switches, manual upgrades don’t scale. Cisco IOS-XE’s Embedded Event Manager (EEM) allows upgrade automation from within the device itself. A simple scheduled EEM applet:
event manager applet SCHEDULED_UPGRADE
event timer cron cron-entry "0 2 * * 6" maxrun 3600
action 1.0 cli command "enable"
action 2.0 cli command "install add file flash:cat9k_iosxe.17.12.04.SPA.bin activate query"
action 3.0 wait 300
action 4.0 cli command "install activate"
action 5.0 syslog msg "Scheduled upgrade initiated by EEM"
For more sophisticated automation — pre-upgrade health checks, per-device decision logic, rollback triggers based on post-upgrade telemetry — Python with Netmiko or NAPALM gives you the full picture externally. See our guide on network automation with Python, Netmiko, and NAPALM for the tooling setup. More EEM scripting patterns are covered in our Cisco EEM scripts guide.
Summary
Catalyst 9000 upgrades done right come down to discipline in the pre-checks, understanding the install mode workflow, and reading the release notes for your target version. The install add / activate / commit workflow gives you a safety net that bundle mode never did. Run your post-upgrade validations, keep an eye on error counters and routing adjacencies, and commit only after you’re confident the switch is behaving correctly. The rollback path is there for a reason — use it if something looks off, and investigate before locking in a questionable software state.