The Monday Morning Config Errors
We jumped from 7.0.6 directly to 7.4.2 on a production HA cluster and came back Monday morning to a unit showing config errors we’d never seen. The cluster had booted. Traffic was passing. The dashboards looked calm enough that my first coffee was still hot when I opened the CLI and saw policy objects, VPN references, and SD-WAN members complaining in ways that did not match the running config I thought we had preserved.
My first assumption was wrong: I treated a successful boot as proof that the upgrade had worked. I had done enough FortiGate upgrades to trust the muscle memory, and that was the mistake. FortiGate upgrade paths require intermediate version stops; 7.0 to 7.4 requires going through 7.2 first, and our direct jump skipped the conversion logic that FortiOS expects to run between major trains.
The box lied politely.
The ugly part was not a hard failure. A hard failure would have pushed us straight into rollback. This was worse because the unit looked alive while behavior was undefined. On FortiOS 7.4.2, several objects existed by name but behaved like partially migrated records, and our HA peer showed a different count for dependent references. I have a strong opinion now: a firewall that boots with corrupted intent is more dangerous than one that refuses to boot.
Reading the Fortinet Upgrade Path Tool Correctly
The Fortinet upgrade path tool is not a suggestion engine in our environment. I treat it as part of the change plan, the same way I treat interface mapping and rollback media. For our failed jump, the path should have been 7.0.6 to a supported 7.2 release, then from 7.2 to the 7.4 train, and later I tested the same approach toward FortiOS 7.4.3 in the lab before touching production again.
What I didn’t expect was how quiet the corruption could be. I expected obvious syntax failures or a failed migration banner. Instead, we got a running firewall with object relationships that no longer matched the operational behavior. That is the reason I now export the tool output as a change artifact instead of relying on memory or release-note skimming.
Trust the boring tool.
Following the Fortinet upgrade path tool and using a 2-stage upgrade took 4 hours but completed with zero configuration issues. Before that, our direct jump took 2 hours and produced 17 configuration errors across policy, VPN, and SD-WAN validation checks. I will take the extra 120 minutes every time, because the shorter maintenance window was fake savings.
Upgrading the HA Cluster Without Guessing
Our production pair runs active-passive HA, so I care about which unit upgrades first and what state the cluster reports between each reboot. I start with the secondary unit, confirm it returns cleanly, watch synchronization, then fail over intentionally before touching the former primary. I do not want the first real failover after a firmware jump to happen under pressure from a WAN incident.
In our runbook, I record the serial numbers, HA priority, monitored interfaces, session pickup setting, and the expected primary before any firmware image is uploaded. With FortiGate clusters, a sloppy upgrade sequence can turn a normal reboot into an argument between peers. I prefer planned leadership changes over surprise elections.
get system ha status
diagnose sys ha checksum cluster
execute ha manage 1
get system status
diagnose debug config-error-log read
No mystery steps.
I also keep console access available for both nodes, even when out-of-band management feels redundant. A web UI session through the management interface is convenient until routing, VLAN tagging, or admin profile behavior changes during the upgrade. My opinion is simple: HA upgrades deserve physical-level humility, even in a highly virtualized manufacturing network.
Building the Pre-Upgrade Safety Net
Before the second attempt, my team tightened the pre-upgrade checklist until it became annoying in the right way. We backed up the config, saved encrypted copies, exported the current firmware image, confirmed local admin credentials, and staged the approved intermediate release. I also ran a small Python 3.11 parser on Ubuntu 22.04 to compare object counts before and after each stage, because manual spot checks miss boring differences at scale.
- Download the full configuration backup from each HA member.
- Save the current firmware image and the target intermediate images.
- Document the rollback trigger, not just the rollback steps.
- Confirm console, management, and break-glass administrator access.
- Reserve a maintenance window that includes validation time.
- Capture pre-upgrade HA, routing, VPN, and policy baselines.
The rollback trigger matters more than the rollback paragraph. In our case, any config-error-log entry tied to policy conversion, VPN phase objects, or SD-WAN member mapping would stop the change. Without that line in the plan, I know we would have debated whether the errors were acceptable.
You may also find this useful: Check out our guide on Python Network Config Backup: Automating Multi-Vendor Device Snapshots for more practical tips.
Ambiguity wastes windows.
I am also strict about backups made immediately before the work, not last week and not after someone says nothing changed. Manufacturing networks collect tiny exceptions: scanner VLANs, vendor tunnels, PLC jump hosts, and temporary rules that somehow become permanent. My opinion is that a firewall upgrade plan without a rollback trigger is just optimism wearing a maintenance-window badge.
Verify Before Calling the Upgrade Done
After the firmware upgrade, I do not declare success when the GUI loads. I verify the control plane, data plane, and configuration migration separately. On the corrected 2-stage path, we checked HA sync, routing tables, IPsec status, SSL-VPN settings, SD-WAN health checks, policy hit counters, address object totals, certificate bindings, and admin authentication behavior before releasing the bridge line and plant operations teams from standby.
I also compare the configuration after each stage, not only at the end. A clean 7.2 landing tells me the first conversion succeeded before FortiOS 7.4.3 ever enters the conversation. If the intermediate version already shows drift, continuing forward only buries the original fault under a newer build number.
Green lights are not proof.
My final verification now includes a deliberate read of the config error log, because the most useful warnings were never on the dashboard that morning. I want the firewall to prove itself in CLI output, HA checksums, real traffic tests, and user-visible application paths before I close the ticket. My opinion is firm: the upgrade path is not paperwork around the real work; it is the work.
Further Reading: For more in-depth information, refer to the official Fortinet Documentation.

