FTD upgrade via FDM API โ major + hotfix¶
โ Complete ยท Captured 2026-07-10 live against the reference 1210CE
Two upgrade flows validated on the same box: major (7.6.0-113 โ 7.6.4-69, 21m 33s) and CC hotfix (7.6.4-69 + CC-7.6.4.1-1, 11m 34s). Every curl transcribed verbatim from the reference build.
Upgrade vs. reset โ different operations¶
- Ch 3.5 Remote factory reset wipes user config, regenerates UUID, requires cross-version FXOS
install security-pack. Destructive on purpose โ used to "return to zero." - This chapter applies a new FTD software version in place, config preserved, via FDM's REST API. UUID stays the same. Same-major-version patches and CC compliance hotfixes are always upgrades, never resets.
Both paths coexist in the guide because Cisco's own docs split them (Reimage Guide vs Upgrade Guide).
Prerequisites¶
- Ch 4 verification complete โ you're logged in to FDM.
- FDM initial-setup wizard skipped (Ch 6 Step 0) โ the REST API is unlocked.
-
The upgrade package downloaded from Cisco.com to your workstation. Portal path (from Ch 3.5 Step 1):
software.cisco.comโ Downloads Home โ Security โ Firewalls โ Next-Generation Firewalls (NGFW) โ Secure Firewall 1200 Series โ Secure Firewall 1210CE โ Firepower Threat Defense (FTD) Software โ target releaseCisco_Secure_FW_TD_1200-<ver>-<build>.sh.REL.tarโ the major/point-release package (~970 MB)Cisco_Secure_FW_TD_1200_Hotfix_CC-<ver>.<hotfix>-<build>.sh.REL.tarโ CC certification hotfix (~220 MB)
Auth¶
FDM_HOST=https://192.168.40.10
FDM_PW=$(bao kv get -field=password infra/webui/fw1210ce-admin)
TOKEN=$(curl -sk -X POST "$FDM_HOST/api/fdm/latest/fdm/token" \
-H "Content-Type: application/json" \
-d "{\"grant_type\":\"password\",\"username\":\"admin\",\"password\":\"$FDM_PW\"}" \
| jq -r '.access_token')
Path A โ Major upgrade (7.6.0-113 โ 7.6.4-69)¶
1. Upload the package¶
curl -sk -X POST -H "Authorization: Bearer $TOKEN" \
-F "fileToUpload=@Cisco_Secure_FW_TD_1200-7.6.4-69.sh.REL.tar" \
"$FDM_HOST/api/fdm/latest/action/uploadupgrade"
Response confirms the file landed at /var/sf/updates/ on the FTD:
{
"name": "/var/sf/updates/Cisco_Secure_FW_TD_1200-7.6.4-69.sh.REL.tar",
"fileName": "/var/sf/updates/Cisco_Secure_FW_TD_1200-7.6.4-69.sh.REL.tar",
"id": "Cisco_Secure_FW_TD_1200-7.6.4-69.sh.REL.tar",
"type": "fileuploadstatus"
}
Empirical: 969 MB uploaded in 69 seconds over the mgmt LAN.
2. Verify the package registered¶
Returns metadata parsed from the package's manifest:
{
"items": [{
"upgradeFileName": "Cisco_Secure_FW_TD_1200-7.6.4-69.sh.REL.tar",
"updateVersion": "7.6.4-69",
"upgradeFrom": "7.6.0",
"rebootRequired": true,
"id": "ebc20059-7c9f-11f1-990f-79fc8521a356",
"type": "upgradefile"
}]
}
Save the id โ it's the target for the readiness check + upgrade.
3. Run the readiness check¶
UPGRADE_FILE_ID="ebc20059-7c9f-11f1-990f-79fc8521a356"
curl -sk -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
"$FDM_HOST/api/fdm/latest/action/upgradereadinesscheck" \
-d "{
\"upgradeFile\": {\"id\":\"$UPGRADE_FILE_ID\",\"type\":\"upgradefile\"},
\"type\":\"upgradereadinesscheck\"
}"
Poll status:
curl -sk -H "Authorization: Bearer $TOKEN" \
"$FDM_HOST/api/fdm/latest/operational/upgradereadinesscheckstatus"
Expect state: "SUCCESS" when done. Empirical: 32 scripts run, 0 failed, 83 seconds.
4. Fire the upgrade¶
Any pending config changes MUST be resolved first. Deploy them or discard them, then:
curl -sk -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
"$FDM_HOST/api/fdm/latest/action/upgrade" \
-d "{
\"upgradeFile\": {\"id\":\"$UPGRADE_FILE_ID\",\"type\":\"upgradefile\"},
\"type\":\"upgradeimmediate\"
}"
If pending changes exist, you'll get:
Discard pending: DELETE /operational/pendingchanges. Or deploy: POST /operational/deploy -d '{}'. Then re-fire the upgrade.
5. Poll upgrade status¶
Sample response mid-upgrade:
{
"state": "IN_PROGRESS",
"updateType": "major",
"baseVersion": "7.6.0-113",
"targetVersion": "7.6.4-69",
"progressPercent": 15,
"message": "Preparing to upgrade... (200_pre/500_stop_system.sh)",
"timeRemainingInSeconds": 2100
}
What to expect during the upgrade¶
Empirical timings from the reference build (7.6.0-113 โ 7.6.4-69):
| Milestone | Wall-clock | Notes |
|---|---|---|
| Upload package (969 MB) | 69s | Multipart POST from workstation over mgmt LAN |
| Readiness check | 83s | 32 scripts; verifies platform support, DB schema, HA state |
POST /action/upgrade accepted |
0s | Instant โ moves upgrade to IN_PROGRESS |
| First 15% progress | ~3m 20s | Pre-upgrade scripts run, FTD apps stop |
| Deep reboot (FDM 503 โ connection refused) | ~5-8m | Kernel boot, filesystem checks, image swap |
| FDM webserver returns (503 โ app initializing) | ~15m from start | HTTP responds again |
| FDM API 200 (upgrade completed) | 21m 33s | state: COMPLETED |
Cisco estimated 41 min in the readiness output; actual was half of that. The estimate is a worst-case ceiling.
Verification โ did the upgrade actually apply?¶
Three checks, in order of strictness:
# 1. Software version (must equal target)
curl -sk -H "Authorization: Bearer $TOKEN" \
"$FDM_HOST/api/fdm/latest/operational/systeminfo/default" | jq '.softwareVersion'
# โ "7.6.4-69"
# 2. UUID (must be UNCHANGED from before upgrade โ proves it was upgrade, not reset)
ssh admin@192.168.40.10 'show version' | grep UUID
# โ UUID: 9179b5e8-7c96-11f1-be1f-f5c66e7fad63 (same as pre-upgrade)
# 3. Config preserved
curl -sk -H "Authorization: Bearer $TOKEN" \
"$FDM_HOST/api/fdm/latest/devicesettings/default/devicehostnames" | jq '.items[0].hostname'
# โ "fw1210ce" (whatever you set in Ch 6)
The UUID unchanged is the definitive test. A reset regenerates it; an upgrade preserves it. Chapter 4 lists this as one of its three "reset actually ran" checks โ same test in reverse.
Path B โ CC hotfix (7.6.4-69 โ 7.6.4.1-1)¶
The Common Criteria hotfix bumps FXOS to a CC-certified build. It's uploaded, checked, and fired via the same API endpoints as the major upgrade โ the platform decides "major" vs "hotfix" based on the package manifest.
Same three commands as Path A, just pointing at the hotfix file:
curl -sk -X POST -H "Authorization: Bearer $TOKEN" \
-F "fileToUpload=@Cisco_Secure_FW_TD_1200_Hotfix_CC-7.6.4.1-1.sh.REL.tar" \
"$FDM_HOST/api/fdm/latest/action/uploadupgrade"
curl -sk -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
"$FDM_HOST/api/fdm/latest/action/upgradereadinesscheck" \
-d '{"upgradeFile":{"id":"<hotfix-id>","type":"upgradefile"},"type":"upgradereadinesscheck"}'
curl -sk -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
"$FDM_HOST/api/fdm/latest/action/upgrade" \
-d '{"upgradeFile":{"id":"<hotfix-id>","type":"upgradefile"},"type":"upgradeimmediate"}'
Hotfix vs major upgrade โ what differs¶
Both are validated end-to-end on the same box. The distinction matters for SEs describing the change to customers:
| Property | Major upgrade | CC hotfix |
|---|---|---|
| Package size | ~970 MB | ~220 MB |
| Upload time on reference LAN | 69s | 18s |
updateType in /operational/upgradestatus |
major |
hotfix |
Full-package softwareVersion bump? |
โ
7.6.0-113 โ 7.6.4-69 |
โ stays 7.6.4-69 |
sspOsVersion (FXOS platform) bump? |
โ
2.16(0.128) โ 2.16(1.147) |
โ
2.16(1.147) โ 2.16(1.1400) |
| UUID preserved? | โ | โ |
| Config preserved? | โ | โ |
| Wall-clock end-to-end | 21m 33s | 11m 34s |
| Dashboard "Software" field shows the change? | โ | โ (dashboard reads softwareVersion) |
| Proof it applied | systeminfo.softwareVersion matches target |
upgradestatus.targetVersion shows 7.6.4.1-1 |
Hotfix silent-success trap
A CC hotfix leaves softwareVersion at the base value โ an SE glancing at the FDM Dashboard after a hotfix cannot tell it applied. The definitive proof lives in GET /operational/upgradestatus (retained after completion) โ targetVersion: 7.6.4.1-1 + updateType: hotfix + state: COMPLETED. Also check sspOsVersion in systeminfo โ the FXOS platform build changes even when the FTD version doesn't.
Roll back within 10 days¶
If the upgrade broke something, POST /action/revertupgrade rolls back to the previous version within the 10-day rollback window:
curl -sk -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
"$FDM_HOST/api/fdm/latest/action/revertupgrade" -d '{}'
Rollback duration is similar to the upgrade itself (~20 min for a major).
Change-record hygiene¶
For regulated fleets, treat every upgrade as an audit event:
- Attach this chapter to the change record
- Include the
sha256sumof the upload package (from Cisco's download page) - Include the pre-upgrade
systeminfo.softwareVersion+sspOsVersionand the post-upgrade values as before/after evidence - Include the
POST /operational/deploypost-upgrade result confirming the config-baseline redeploy succeeded (see Ch 6 Step 8's poll pattern)
Related¶
- Ch 3.5 Remote factory reset โ the destructive alternative when you need "return to zero"
- Ch 6 FDM baseline โ deploy pattern reused here
- Ch 14 Licensing โ upgrade behavior + Smart License registration relationship
Next¶
If the upgrade landed, proceed to Ch 5 โ Choose your management path or resume whatever chapter you were on.