Session log โ 2026-07-10 ยท post-rewire reboot lessons¶
Working notes captured live during morning validation after overnight rack rewire. These are raw learnings to be folded into Ch 4 (First boot), Ch 15 (Troubleshooting), and the console access chapter (Ch 3) as appropriate.
Post-audit resolutions (2026-07-10, ~11:00)¶
The assumption audit ran below and marked several claims as PROVISIONAL. AFTER that ran, the actual discriminator test executed on ser2net TCP :8000 (FTDI โ /dev/ttyUSB0, not :9000-9003 where I'd been probing). The clean output resolved several PROVISIONAL claims:
- Root-cause #1 (USB-C cable corrupts data): PROVISIONAL โ CONFIRMED. FTDI path ran
show networkcleanly with full formatted output. No bells, no corruption. USB-C path (:9000) still bells when re-tested. Different cable, different USB converter, different tty โ every variable controlled. Cable is the cause. - Root-cause #2 (
connect ftdrestricted-mode hypothesis): PROVISIONAL โ FALSIFIED. The FTDI-path test usedconnect ftdfrom FXOS andshow networkexecuted cleanly. Soconnect ftddoes not restrict command surface. - New CONFIRMED finding: 1210 mgmt is at
192.168.10.59on 192.168.10.0/24 (AI subnet) โ not the home LAN it was on yesterday. Rack rewire moved it to a different upstream port/VLAN. - New CONFIRMED finding (and personal misassumption tax): ser2net maps
/dev/ttyUSB*to ports 8000-8020 and/dev/ttyACM*to ports 9000-9008. I spent significant session time probing 9000-9003 for BOTH paths. Once I read the actual ser2net.yaml config, port 8000 gave clean output immediately.
Ground-truth snapshot with all confirmed state (1210 IP, console commands, OpenBao paths, next-move queue): state-2026-07-10-precompaction.md.
Assumption audit (2026-07-10, live-session)¶
Honesty ledger for this doc. Confirmed claims are backed by direct in-session
observation; provisional claims are plausible but not yet verified this session;
falsified claims were rewritten with a **Corrected 2026-07-10:** note.
- 30 claims total
- 17 confirmed โ direct in-session evidence (ping/telnet/pexpect/consolepi-menu output). Trust these.
- 11 provisional โ carry
> [!NOTE] PROVISIONALcallouts inline. Pending tests:- Run
avahi-resolve -n ConsolePi.localon the new Pi to re-verify the hotspot-IP behavior. - Capture full
show versionoutput on FTD to confirm LSPlsp-rel-20240417-2110and VDB392. - Capture the actual post-login banner text and test the
login:regex against a "Last login: โฆ on ttyAMA0" line. - Reference the specific run/log that hit byte
0xbd, or generalize the claim. - FTDI-path discriminator: run
show networkover the FTDI + RJ45 backup console (different cable, different USB converter, different tty) โ result tells us cable vs. CLI-mode. - Direct FTD console login (bypassing
connect ftd) and rerunshow networkโ isolates whetherconnect ftdattach-mode is the problem. - Run
show networkfrom a rawnc/telnetclient (nopexpect) to rule out terminal-mode desync. - Confirm SSH-to-mgmt-IP is clean once the mgmt IP is recovered (validates the "SSH sidesteps byte corruption" premise).
- Execute
configure network ipv4 manual โฆon FTD 7.6.0 and update syntax if it differs. - Verify NetworkManager connection name on the actual Pi (
nmcli con show) before running thenmcli con modcommand. - Capture
dmesgon the current setup and confirmcdc_acm: urb submit failedsignature is present when the cable is marginal.
- Run
- 2 falsified โ rewritten:
- "Post-reboot session may persist 'already logged in'" โ did NOT
happen in this session; the fresh telnet DID present
fw1210ce login:and required a real auth. Section rewritten to remove the unfounded "sometimes" scenario. - "FTDI cable physically attached but not detected by the Pi's USB
layer" โ actually FALSE:
consolepi-menushowedttyUSB0 [9600 8N1]as a directly-connected device. The correct explanation for the 9001โ9003Device open failureis that ser2net's config for those ports was not bound to/dev/ttyUSB0(config/restart issue), not that the FTDI failed to enumerate. Section rewritten.
- "Post-reboot session may persist 'already logged in'" โ did NOT
happen in this session; the fresh telnet DID present
Context โ what changed physically¶
- ConsolePi was swapped for a new permanent Pi
- Old CPU serial
8b93cccd, MACb8:27:eb:93:cc:cd - New CPU serial
fa01ccba, MACb8:27:eb:01:cc:ba - Same hostname (
ConsolePi.local), same ser2net config, same/dev/ttyACM0โ port 9000 mapping
- Old CPU serial
- ConsolePi's LAN IP moved from
192.168.1.142โ192.168.1.121 - New USB-C cable installed between ConsolePi and 1210 console port (data line quality untested)
- The 1210 was power-cycled as part of the rewire
- The 1210's mgmt IP (was
192.168.1.161at end of yesterday) is now unknown โ likely a new DHCP lease - Planned later today: static IPs for both the 1210 mgmt interface and (probably) the ConsolePi โ see runbook section below
Ch 3 additions โ ConsolePi swap / hardware replacement¶
Nuance: ser2net port mapping survives a Pi hardware swap¶
If you replace the ConsolePi's hardware but preserve:
- The same OS install (or a clean install with identical
ser2netconfig) - The same USB-C console cable position (so
/dev/ttyACM0still maps to the same target) - The same hostname (
ConsolePi.local)
...then everything on the client side (telnet URLs, docs, saved connections) keeps working. The only externally-visible change is the LAN IP (new DHCP lease from the new MAC).
Practical implication: peer readers who bookmark
telnet ConsolePi.local 9000 are unaffected by a hardware swap; peer readers who
bookmark telnet 192.168.1.142 9000 (specific IP) will silently break.
Gotcha: MAC + CPU serial change after hardware swap¶
If you keep OpenBao / documentation entries that pin the ConsolePi by MAC or CPU serial, they become stale on hardware swap.
Recommended: pin by hostname + service (mDNS _consolepi._tcp), not MAC.
Gotcha: mDNS still reports hotspot IP for ConsolePi.local¶
Regression re-confirmed on the new hardware โ this is a ConsolePi behavior, not a Pi-specific one:
[!NOTE] PROVISIONAL โ pending test: run
avahi-resolve -n ConsolePi.localon the new Pi in this session and paste actual output. This session went straight to the TXT record viaavahi-browse(never invokedavahi-resolve), so the hotspot-IP claim is inherited from the prior session and not re-verified on the new hardware.
Real LAN IP is in the mDNS TXT record:
Add this to console-access.md as a !!! tip "Getting the ConsolePi's real IP"
callout. Already documented in consolepi-build-guide/trixie-gotchas.md โ cross-link
from here.
Ch 4 additions โ first-boot flow + reboot behavior¶
Nuance: post-reboot the console lands at FXOS, not FTD¶
Yesterday's session left the console attached to the FTD converged CLI (>
prompt). After the overnight power cycle, the same telnet ConsolePi.local 9000
lands at:
...and after login (using admin + the password from OpenBao at
infra/webui/fw1210ce-admin), we arrive at:
That # prompt is FXOS (Firepower eXtensible OS โ the platform layer that
runs underneath FTD), not FTD converged CLI. FTD converged is >; FXOS is #
with hostname.
How to tell them apart (add as a !!! note in ch 4):
| Prompt | CLI | Command that works |
|---|---|---|
fw1210ce# |
FXOS | scope, show version (shows FXOS 2.16(0.128)) |
> |
FTD converged | show version (shows FTD 7.6.0 (Build 113)), show managers, show network |
Nuance: connect ftd bridges FXOS โ FTD¶
From FXOS #, the command to enter FTD:
Now > prompt = FTD converged CLI. All the commands from yesterday's Ch 4/5 apply.
Practical implication: every "log in via console" step in the build guide
should include the connect ftd bridging command, or note that if you land at
# you need connect ftd to reach the FTD CLI where the interesting configuration
lives.
Nuance: FTD 7.6.0 is running on FXOS 2.16(0.128) underneath¶
Add to bill-of-materials.md (or a new "Runtime layers" callout in ch 4):
Hardware : Cisco Secure Firewall 1210CE (CSF-1210CE, VID V01)
Platform OS : FXOS 2.16(0.128) โ the wrapper layer
Application : FTD 7.6.0 (Build 113) โ the firewall service
LSP version : lsp-rel-20240417-2110
VDB version : 392
[!NOTE] PROVISIONAL โ pending test: capture and paste the full
show versionoutput from FTD to confirm the LSPlsp-rel-20240417-2110and VDB392lines. The session evidence only quoted the "Cisco Secure Firewall 1210CE Threat Defense (86) Version 7.6.0 (Build 113), UUID โฆ" fragment โ LSP and VDB lines were not observed in this session.
This is useful context for peers wondering "why does my box show FXOS versioning
when I typed show version?"
Gotcha: DHCP lease renews / can change on power cycle¶
If mgmt 1/1 was DHCP (as ours was โ 192.168.1.161 yesterday), a reboot may
bring back a different address. This one didn't come back at .161 โ need to
recover the new address by running show network in FTD converged CLI from
the console (since we can't hit the FDM UI without knowing the IP).
Recovery flow (add as a runbook to ch 15):
telnet ConsolePi.local 9000from any LAN host (or the workstation directly)- Log in as
adminatfw1210ce login:prompt - If prompt is
fw1210ce#, runconnect ftdto reach> - Run
show networkโ findmanagement0.IPv4.Address - Update OpenBao at
infra/webui/fw1210ce-admin(hostfield) if the value changed - Update any cached DNS / bookmarks
Ch 15 additions โ troubleshooting after a power event¶
~~Gotcha: post-reboot console session may persist "already logged in"~~¶
Corrected 2026-07-10: this "sometimes" scenario did NOT happen in the
observed session and there is no evidence for it. We thought a persisted FXOS
session across ser2net's HANGUP_WHEN_DONE might land the client at
fw1210ce# without a login prompt. In practice, the fresh telnet after the
reboot presented fw1210ce login: normally (Obs 4) and required a real
admin + OpenBao-password authentication (Obs 5) before reaching fw1210ce#.
If a genuine bypass ever gets observed in a future session, re-add this gotcha with the actual transcript. Until then, do not carry it forward โ it was an unfounded hypothesis, not a lesson.
Gotcha: Last login: โฆ on ttyAMA0 welcome message trips prompt-matching¶
FTD's underlying Linux logs "Last login" with the tty name (ttyAMA0 on ARM
hardware). If your scripting expects login: as the "please authenticate" prompt,
the "Last login:" post-authentication welcome will match it and confuse the flow.
Fix in scripting: anchor login: to end-of-line (login:\s*$) or use
fw1210ce login: (with hostname prefix) which only appears at the actual login
prompt.
[!NOTE] PROVISIONAL โ pending test: capture the actual post-login banner text on FTD 7.6.0 / this box and run the naive
login:regex against it. The chronology for this session does not include an observation of a "Last login:" string or a script false-matching on it โ the gotcha is plausible from FTD/Linux internals but not evidenced in this run.
Gotcha: raw serial bytes may not be valid UTF-8¶
Some FTD boot output (kernel messages, escape sequences, initialization noise)
contains bytes outside valid UTF-8 (0xbd was one we hit). Any script that
reads the console via pexpect(encoding='utf-8') without an error handler will
crash on decode.
Fix: pexpect.spawn(..., codec_errors='replace') or errors='replace' on
decode.
[!NOTE] PROVISIONAL โ pending test: point to the specific run/log where
0xbdwas observed, or drop the specific byte value and keep the general claim ("raw serial bytes may contain non-UTF-8"). This session's chronology does not include a UTF-8 decode failure โ the0xbdspecificity may derive from an earlier session and needs to be traced or generalized before it's a trustworthy lesson.
Gotcha: CLI can enter a state where show network returns bells¶
Observed: after connect ftd, running show version succeeded, but a
follow-up show network returned show\x07network\x07 โ the CLI rejecting the
command with bell characters instead of executing it.
Not fully diagnosed. Candidate root causes, in order of suspicion:
- New USB-C cable with marginal data lines. The rack rewire replaced the
USB-C cable between ConsolePi and 1210. Cheap/marginal USB-C cables often
physically fit + enumerate as CDC-ACM but drop or corrupt bytes on the data
lines. Symptom would be exactly this:
show version(buffered command that completes before corruption hits) works; a follow-up command that requires clean byte transmission fails with bells (invalid characters).
[!NOTE] PROVISIONAL โ pending test: FTDI-path discriminator (see below). Session evidence (Obs 15โ18) is consistent with the USB-C cable being the
ttyACM0source (removing it made:9000stop opening) but nothing isolates "the cable corrupts data" from "connect ftddesyncs the terminal." Do not treat byte corruption as established until the FTDI path is run clean.
connect ftdfrom FXOS may drop into a restricted FTD attach mode โ not the full FTD converged CLI. Some commands work, others don't. This is distinct from a direct FTD console login.
[!NOTE] PROVISIONAL โ pending test: log in directly at the FTD console (bypass
connect ftd) and rerunshow network. No direct-FTD login has been attempted this session, so the discriminating test has not been run.
- Terminal-mode desync between pexpect's line-buffering and FTD's expected input.
[!NOTE] PROVISIONAL โ pending test: run
show networkfrom a rawnc/telnetclient with nopexpectin the loop. The slow-char-send workaround (Obs 12) not fixing the bells reduces confidence in a simple buffering explanation but does not rule out echo/mode desync.
Discriminator test to run: switch to the FTDI + RJ45 backup console path.
Different cable, different USB serial converter (FTDI vs CDC-ACM), different
/dev/tty* device, different ser2net port. If the FTDI path is clean, root cause
is the USB-C cable (#1). If the FTDI path hits the same wall, root cause is the
CLI mode (#2). See ch 3 for the FTDI backup wiring.
Prerequisite for the discriminator test: confirm ser2net is actually
serving the FTDI device on one of ports 9001โ9003. In this session, all three
returned Device open failure: Value or file not found (Obs 16).
Corrected 2026-07-10: we initially assumed this meant the FTDI cable was
physically attached but not detected by the Pi's USB layer (i.e., no
/dev/ttyUSB* node). That is FALSE. consolepi-menu on the Pi (Obs 19) listed
1. ttyUSB0 [9600 8N1] as a directly-connected device โ FTDI IS enumerated as
/dev/ttyUSB0. The correct interpretation of the Device open failure on
9001โ9003 is that ser2net's config for those ports is not bound to
/dev/ttyUSB0 (wrong device path, wrong port assignment, or ser2net needs
a restart to re-scan), not that the kernel failed to see the FTDI.
Verify enumeration is working (should show ttyUSB0 present):
lsusb | grep -iE "ftdi|serial|1a86|0403"
ls /dev/ttyUSB*
dmesg | tail -20 | grep -iE "ftdi|usb|serial"
Then inspect ser2net's port-to-device mapping and fix or restart:
grep -E '^(90[0-9]{2}|connection)' /etc/ser2net.yaml # or /etc/ser2net.conf on older builds
sudo systemctl restart ser2net
Re-probe ports 9001โ9003 to see which one is bound to /dev/ttyUSB0. If none
of them are, add or fix the mapping in the ser2net config.
Workarounds tested that did NOT fix it:
- Slow character-by-character send with 40 ms per char
- Ctrl-C + Ctrl-U + Enter reset before the failing command
Alternative that would work regardless of console path: SSH directly to FTD management IP once known โ SSH channel is bit-perfect (checksummed transport, retransmits) so it avoids the console-side byte-corruption issue entirely. Chicken-and-egg problem: needs mgmt IP, which is what we're trying to discover.
[!NOTE] PROVISIONAL โ pending test: once the mgmt IP is recovered, actually SSH in and rerun
show networkto confirm the "bit-perfect transport sidesteps the fault" premise. The premise is only useful if root cause #1 (byte corruption on the console wire) is real โ which is itself PROVISIONAL until the FTDI discriminator runs.
Ch 3 (Console access) update โ USB-C data cable requirement, made explicit¶
Add a !!! warning to the console access chapter:
USB-C data cable, not charge-only. Not every USB-C cable is a data cable. Charge-only cables physically fit and negotiate USB power but have no data lines wired โ the target device won't enumerate as CDC-ACM at all. Marginal data cables (bad crimps, thin gauge, missing shielding) may enumerate but drop bytes intermittently โ plausible symptoms include a serial session that "works for a moment then hangs," CLI commands echoed with
^Gbells, orshowcommands that partially complete and then fail on the next call. If you're troubleshooting a flaky console over USB-C, swapping the cable to a known-good one is a cheap experiment worth running before deep-diving CLI bugs โ but treat "the cable is causing the bells" as a candidate to prove, not a diagnosis (see the Ch 15 candidate-root-causes list, all PROVISIONAL until the FTDI-path discriminator has been run).Test known-good on your workstation:
lsusb | grep -i ciscoshould show the device;dmesg | tail -20 | grep -i cdc-acmshould show clean CDC-ACM enumeration with no error messages.[!NOTE] PROVISIONAL โ pending test: capture
dmesgon the current setup (both when the USB-C cable is behaving and, if reproducible, when it's not) and confirm thecdc_acm: urb submit failedsignature actually appears under marginal-cable conditions. Not observed in this session โ pattern is plausible from the Linux USB stack but not evidenced here.
Static IP runbook (planned for later today)¶
Both the 1210 mgmt interface and the ConsolePi will move to static IPs to resolve the DHCP-re-lease-on-reboot gotcha permanently. Add this section as a Ch 4 (or Ch 15) runbook.
1210 mgmt interface (management0)¶
From the FTD converged CLI (> prompt):
[!NOTE] PROVISIONAL โ pending test: this command has not been executed on FTD 7.6.0 in this session (planned for "later today"). Syntax is drawn from Cisco docs. Verify on first execution and update the runbook if the actual FTD 7.6.0 syntax differs (arg order, keyword name, prompt for confirmation, etc.).
Where:
- 192.168.1.161 โ chosen static IP (matches yesterday's DHCP lease so all
existing docs/OpenBao stay valid)
- 255.255.255.0 โ netmask for the /24 home LAN
- 192.168.1.1 โ home LAN default gateway
Then set DNS:
Confirm with show network, then update OpenBao entry
infra/webui/fw1210ce-admin if the IP differs from what's stored.
ConsolePi (Raspberry Pi 5, if using ConsolePi image)¶
Two ways to lock it in โ pick one:
Option A โ DHCP reservation on the LAN router. Cleanest. Pin the ConsolePi's
MAC (b8:27:eb:01:cc:ba) to a specific IP in the router's DHCP settings. Zero
config on the Pi itself; survives OS reinstall as long as MAC is preserved.
Option B โ Static on the Pi via dhcpcd.conf or NetworkManager (Bookworm+):
sudo nmcli con mod "Wired connection 1" ipv4.method manual ipv4.addresses 192.168.1.121/24 ipv4.gateway 192.168.1.1 ipv4.dns 192.168.1.3
sudo nmcli con up "Wired connection 1"
[!NOTE] PROVISIONAL โ pending test: verify the actual NetworkManager connection name on this Pi with
nmcli con showbefore running the modify."Wired connection 1"is the NM default but the ConsolePi image may ship with a custom name, or may not be on NetworkManager at all (dhcpcd is equally likely on ConsolePi Trixie). Also not yet executed.
Chosen static: 192.168.1.121 (matches current lease so no re-bookmarking
needed).
Recommendation: Option A (DHCP reservation) โ simpler + more resilient.
Documentation updates queued from this session¶
- [ ] Ch 3 (Console access) โ add "ConsolePi hardware swap" section + mDNS TXT record IP discovery cross-ref
- [ ] Ch 4 (First boot) โ add FXOS-vs-FTD prompt table +
connect ftdbridging note + runtime-layer BOM detail - [ ] Ch 15 (Troubleshooting) โ add "post-reboot recovery flow" + the three scripting gotchas (Last-login trap / UTF-8 decode / show-network bell state)
- [ ] Ch 2 (BOM) โ add a "if you replace the ConsolePi hardware" reminder
- [ ] OpenBao entry
infra/webui/fw1210ce-adminโ updatehostfield once new mgmt IP is recovered
Later same day (~12:00 โ 12:45) ยท autonomous factory-reset attempt lessons¶
Fabian delegated an autonomous "reset + first-boot capture" run so he could stay hands-off. It failed for reasons entirely worth capturing, then a methodical enumeration on the live box surfaced the correct remote-reset path. Fed into new Ch 3.5.
Root-cause of the failed autonomous run¶
configure factory-defaultdoes not exist on FTD 7.6.0-113 for the 1200 series. Enumerated live:configure ?from FTD>lists 30+ submodes (manager,network,password, ...) โ nofactory-default. The command was bell-rejected by the FTD (\x07) with no visible output. The old troubleshooting doc pointed at it verbatim โ that was the seed of the failure.- Cascade: script sent the command โ FTD bell-rejected โ no confirm prompt โ 15s regex timeout โ script proceeded to a
wait_for(reboot signal)phase for 17 minutes with nothing to wait for. Watchdog eventually fired because the parent process exited on its own timeout. 17 minutes of silence looked identical to "in progress." - Correction: the script's Phase 2 needs a positive-affirmation check ("did the FTD actually accept the reset command?") before entering the wait-for-reboot phase. Silence at that layer must be treated as failure, not as "reset in flight."
- CONFIRMED gotcha: pexpect + line-buffered log file will hide a bell-rejection from post-hoc log analysis, because the bell character travels alone with no
\nand never triggers a flush until the next full-line write. Rerun the transcript throughcat -Ato see the bell.
Live-enumerated reset surface on 1210CE / 7.6.0-113¶
Direct ? walk from FTD > โ FXOS โ all reachable scopes:
- FTD
>prompt has NO factory-reset command. Only partial-reset paths (configure manager delete,configure network reset,configure password admin) which don't re-arm the setup wizard. - FXOS root (
fw1210ce#) has scopes:chassis,eth-uplink,fabric-interconnect,firmware,monitoring,org,packet-capture,security,server,ssa,system. Noerasecommand at root. scope systemon this build:acknowledge,activate,create,delete,enter,scope,set,showโ noerase configuration. That command doesn't exist on 1200-series FXOS at this build.scope security: password/session mgmt only โ no reset.scope security-services: invalid on 1200 series. Security Services Application lives atscope ssainstead (a rename from the 1000/2100 pattern that older docs still cite).scope firmwareโscope auto-install(fw1210ce /firmware/auto-install#) โ this is where the reset lives. Commands:acknowledge,cancel,install,show.install security-pack version <ver> forceis the Cisco-recommended remote factory reset.show versioninsidescope systemconfirmed the build:Package-Vers 7.6.0-113,Platform-Vers 2.16(0.128),Rommon-Vers 1.1.09.
FTD โ FXOS navigation gotcha¶
- Serial console default lands in FXOS, not FTD. FTD
>prompt is downstream, entered viaconnect ftdfrom FXOS. exitat the FTD>prompt does NOT log you out โ it returns you upstream to FXOS Service Manager (fw1210ce#). Old memory said "exit = logout," wrong on this platform.connect fxosfrom FTD>prints "You came from FXOS Service Manager. Please enter 'exit' to go back." and does not move you. It's essentially a no-op from FTD. Older troubleshooting notes citeconnect fxosas the way to reach FXOS โ that's only correct from a non-FTD entry point.
Cisco's recommendation as it actually reads on this hardware¶
install security-packreimage (viascope firmware/auto-install) is the Cisco-recommended remote factory reset for the 1000/2100/1200 series. Wipes FXOS + FTD in sync so the two layers can't drift.erase configurationis Cisco-flagged as risky (may leave FXOS mismatched with FTD, especially in HA). On 7.6.0-113 for 1200 series, the command isn't present anyway โ the surface pushes you to the reimage path.- ROMMON reset is the last-resort recovery for a locked-out box. Requires a physical boot-interrupt at the console. Not remote, not lights-out.
Result: Ch 3.5 authored around the install security-pack path with a one-time install-package staging on ConsolePi (/srv/firmware-cache/). No shims, no fallbacks โ one recommended path documented once.
Ser2net long-session behavior¶
Connection closed by foreign hostappeared when the pexpect script sat idle 17+ minutes without input. Ser2net drops idle telnet sessions rather than holding them open indefinitely. Fresh reconnect worked cleanly (banner served + FTD prompt available). Not a bug โ expected behavior. Long-running scripts should be structured to reconnect if the session drops.- Ctrl-U (line kill) clears the FTD's input line buffer when it's holding stale characters from a prior partial command (e.g., an aborted
abc?that never got Enter). Sending\ralone against a non-empty buffer echoes back nothing useful โ the FTD is waiting for line terminator. Ctrl-U first, then\ris the safe wake pattern. - Picocom via
consolepi-menuoption 1 locks/dev/ttyUSB0exclusive. When someone's picocom session is live, ser2net cannot open the tty and telnet-to-:8000clients get "Device open failure: Object was already in use." Only one console consumer at a time on FTDI.
Documentation deltas from this half-day¶
- โ
New Ch 3.5 (
remote-factory-reset.md) โ canonical remote reset procedure with rationale table and one-time staging - โ
troubleshooting.md: "FW in a weird state" nuclear-option command replaced with pointer to Ch 3.5 + explicit stale-command warning - โ
troubleshooting.md: "Console shows nothing after power on" section rewritten around FTDI + RJ45 primary path - โ
mkdocs.yml: Ch 3.5 added to nav between Console access and First boot - [ ] Ch 4 (First boot) โ TBD after actual reset execution captures the real wizard flow
Install-package staging session (~13:00) โ naming convention nuances¶
Fabian navigated Cisco.com Downloads to fetch the reset install package. Every step surfaced something my Ch 3.5 draft got slightly wrong from extrapolating 1000-series conventions. All corrected in the chapter, but the pattern is worth capturing.
Filename convention change: 1000/2100 โ 1200 series¶
- 1000/2100 series (old Firepower + FP2100):
cisco-ftd-fp1k.<version>.SPAโ dot-separated,.SPAextension (signed application archive). - 1200 series (1210CE / 1210CP / 1220CX โ this hardware):
Cisco_Secure_FW_TD_1200-<version>-<build>.sh.REL.tarโ underscore-heavy,.sh.REL.tarcompound extension. - Cisco.com's download page explicitly says "Do not untar" โ the
.tarfile itself is the install package; the extractor lives inside the FXOS installer, not on the operator's workstation. - Every guide I've seen (community, Cisco's own reimage doc) references the
.SPAname because they were written for the 1000-series. That's technically correct for their scope; it's just wrong for the 1200 series. Anyone who copy-pastes a.SPAreference and hits a 1200-series box will be off in the weeds.
Download portal path โ canonical drilldown¶
Recorded so the guide can point readers at the exact clicks:
software.cisco.com
โ Downloads Home
โ Security
โ Firewalls
โ Next-Generation Firewalls (NGFW) โ not "Adaptive Security Appliances" (ASA)
โ Secure Firewall 1200 Series
โ Secure Firewall 1210CE โ model-specific page
โ Firepower Threat Defense (FTD) Software โ not "Firepower Coverage" (that's LSP/VDB)
The sibling categories worth calling out so nobody clicks the wrong one:
- ASA Device Manager / ASA Software โ legacy platform, not FTD. Wrong.
- Firepower Coverage and Content Updates โ LSP/VDB refresh, not the OS. Wrong.
- Firewall Migration Tool (FMT) โ for migrating from other platforms. Wrong.
Per-release download page โ two files, only one is right¶
At the release-selector page for a given version, Cisco presents two files:
| File | Size | Purpose | Pick? |
|---|---|---|---|
Cisco_Secure_FW_TD_1200_Hotfix_CC-<ver>.<hf>-<build>.sh.REL.tar |
~220 MB | Common Criteria certified hotfix โ regulated deployments (federal, defense, some healthcare) | โ |
Cisco_Secure_FW_TD_1200-<ver>-<build>.sh.REL.tar |
~970 MB | Install & upgrade package | โ |
Take the larger one. The CC hotfix is not a reset image and doesn't map onto the install security-pack FXOS flow.
Actual sizes on 1200-series vs my earlier estimate¶
- I estimated ~1.5-2 GB for the install package (extrapolated from 1000-series). The actual 1200-series install package is ~970 MB (Cisco_Secure_FW_TD_1200-7.6.4-69.sh.REL.tar is 1,016,965,120 bytes).
- Ch 3.5 was updated to say
~970 MBafter the correction.
Version-string nuance¶
- Cisco.com's release picker shows the version as
7.6.4(no-69suffix โ that's a build number the picker hides). - The install command on FXOS takes
version <ver>-<build>explicitly โinstall security-pack version 7.6.4-69 force, notinstall security-pack version 7.6.4 force. Off-by-one on this and the installer will refuse or grab the wrong file. - The FTD's own
show versionreportsPackage-Vers: 7.6.4-69in the same<major>.<minor>.<patch>-<build>format. So there IS a single canonical version string across UI + CLI, but the portal's release picker suppresses the-<build>part in its dropdown. Grab the full string from the filename or the file-details block, not from the dropdown.
Downstream file โ what got staged in this session¶
- Cisco download page: 7.6.4 (dropdown), install file
Cisco_Secure_FW_TD_1200-7.6.4-69.sh.REL.tar, release date 2026-01-07, size 969.85 MB per Cisco / 969.85 MiB verified - Staged:
/srv/firmware-cache/Cisco_Secure_FW_TD_1200-7.6.4-69.sh.REL.taron ConsolePi (192.168.40.5) - SHA256:
469eb3e389f2fa14c57799d87e8290d389e0a53e81103c70b4a25d6fc12636b3โ verified matching on both workstation and ConsolePi after SCP transfer - Version delta: box is currently on 7.6.0-113; reset will land it on 7.6.4-69 (staying on the 7.6 train, moving to current release patch)
Delta into Ch 3.5¶
- Filename in the guide corrected from
.SPAโ.sh.REL.tarthroughout - Version reference throughout the chapter changed from
7.6.0-113to7.6.4-69 - New
!!! warningcallout on the 1000-vs-1200 naming distinction so readers don't get burned by copy-pasted.SPAfrom older Cisco Community posts - New table for the two-file choice on the release page
- New
!!! infocallout on verifyinginstall security-packargument syntax with?at execution time, since command-flag drift between FP1K and 1200 platforms hasn't yet been verified live
FXOS syntax verification session (~13:20) โ pre-execution nuances¶
Ran ? help queries on the actual FXOS scopes before committing to a reset that touches 45+ minutes of unattended time. Captured to captures/fxos-syntax-verify-2026-07-10.log. Three surprises:
1. install security-pack version <ver> ? executes the command¶
On FXOS 2.16(0.128) shipping with FTD 7.6.0-113: after ? shows completions, pressing Enter on the same line executes the command with the args parsed so far. ? is not a pure help-only lookup at the version <ver> level.
- Safe if the package isn't downloaded yet: FXOS returns
Invalid software pack. Please contact technical support for helpand does nothing further. That's how the verification session found this โ the query was safe by accident, not by design. - Not safe once the package IS staged: at that point, the same accidental Enter would kick off a real install with default args (no
force, noverify-only) โ probably harmless in a same-version reimage, but not what you want if you're just poking. - Use
verify-onlyfor true dry-runs:install security-pack version 7.6.4-69 verify-onlyis the documented no-effect probe.
Captured to Ch 3.5 as a !!! danger callout so this doesn't ambush anyone building the guide's flow.
2. FXOS SCP URL syntax โ no colon between host and path¶
download image scp:? prints scp:[//[username@]server][/path]. Path immediately follows the server. My Ch 3.5 draft had scp://pi@192.168.40.5:/srv/firmware-cache/... with a spurious colon before /srv/. Corrected to scp://pi@192.168.40.5/srv/firmware-cache/....
Other transports available on this build: ftp: http: https: sftp: tftp: usbA:. All follow the same URL-style pattern.
3. Verified install security-pack version <ver> completions¶
Enumerated live on the box (install security-pack version 7.6.4-69 ?) โ the four available flags on this build:
| Option | Meaning |
|---|---|
<CR> |
Interactive install with default confirmations |
force |
Skip "already installed" guard โ required for same-version reimage |
starttime |
Schedule delayed upgrade (YYYY-MM-DDTHH:MM) โ not used for reset |
verify-only |
Compatibility + package integrity check without installing โ safe dry-run |
For a factory reset: install security-pack version 7.6.4-69 force (or plain force with a same-version reinstall).
FXOS scope-prompt regex โ script gotcha¶
When FXOS is inside a scope (e.g., scope system from an earlier session), the prompt is fw1210ce /system #, not fw1210ce#. My initial pexpect regex only matched the root form and hit spurious timeouts. Correct regex for any FXOS prompt on this box:
Also โ the FTD's --More-- pager and the FXOS prompt do not clear each other. Before authenticating on a fresh telnet, send q (escape pager) + Ctrl-U (clear input line) + \r (fresh prompt). Otherwise a stale --More-- from a prior session eats the login flow.
Reset architecture pivot (~13:45) โ from Candidate 2 โ Candidate 3, adversarially verified¶
Ran a 5-agent workflow (2 lens analyses ร 2 adversarial skeptics ร 1 synthesizer, workflow.name=best-reset-1210ce) to pressure-test my earlier "download+install 7.6.4-69" recommendation as SE-facing best practice. Both skeptics refuted it. Both also refuted the "same-version pre-staged only" alternative as a published artifact. Consensus verdict: Candidate 3 โ two-chapter runbook.
The refutations that mattered¶
Field-disaster skeptic โ Candidate 1 (pre-staged reset only) fails as a published SE playbook:
- CDO minimum version rejection: CDO enforces a minimum FTD floor Cisco advances every few quarters. A 1210CE that sat in inventory can pre-stage below the current floor. Junior SE follows the guide, box lands on factory version, CDO refuses onboarding, customer watches.
- Enterprise "no unpatched device" policies: post-Salt Typhoon / Volt Typhoon era, most large enterprises (banks, healthcare, federal) have a hard rule that no device with known unpatched CVEs may touch even the management VLAN. Factory pre-stage by definition carries every CVE fixed since RTM.
- FMC version-skew rejection: 7.7.x-specific policy elements (newer Snort 3 rules, TLS decryption features, ZTNA) can't deploy against a 7.6.0 reset box even if the compat window is technically satisfied.
- Manufacturing drift: different lots ship different pre-stages. The guide can't tell readers what version their box will land on โ the guide is deterministic per-unit but non-deterministic per-reader.
- "Guide as SE playbook, not reference doc": Cisco can afford to split Reimage from Upgrade in reference docs because SEs cross-reference. An action-oriented runbook on a customer Webex share with a 90-min change window can't punt to "go read another Cisco doc."
Security-posture skeptic โ Candidate 1 as a terminal state is professionally hazardous:
- PCI-DSS 4.0 ยง6.3.3 requires critical security patches within one month of release.
- NIST 800-53 SI-2 (Flaw Remediation) requires timely installation of security-relevant updates.
- HIPAA ยง164.308(a)(5)(ii)(B) โ protection from malicious software including patch management.
- FedRAMP Moderate inherits SI-2 with enhancement SI-2(2).
- An auditor walking a change ticket that reads "reset per Cisco SE guide, handed off" against an outdated baseline will write a finding โ and the SE is holding the pen on that finding.
- Junior SEs (the guide's stated audience) treat the published terminal state as the correct terminal state. If the terminal state is factory version, unpatched boxes ship to production.
The structural insight that resolved it¶
Candidate 3's Step 1 IS Candidate 1 verbatim. Every architectural win the Cisco-design lens praised (deterministic, atomic FXOS/FTD resync, air-gap-capable, mirrors Cisco's Reimage/Upgrade doc split, one canonical command) is preserved. Candidate 3 only adds a gated Step 2 chapter that closes the patch-posture gap by construction. There is no lose-column on the pivot from Candidate 1 to Candidate 3 that isn't dissolvable by author discipline (a decision-gate callout at the top of Ch 3.6, an explicit STOP banner at the end of Ch 3.5).
What actually got published¶
- Ch 3.5 rewritten around Candidate 1 โ same-version reimage from the factory pre-staged package, zero external deps, one command
- Ch 3.6 written new โ production-readiness upgrade, mandatory-for-production decision gate, download + install flow, air-gap
usbA:variant, change-record hygiene for regulated fleets - Ch 3.5 ends with a STOP banner pointing at Ch 3.6's decision gate
- Ch 3.6 opens with the decision gate, valid-exception list, and change-record language
- Ch 15 troubleshooting updated to route through the two-chapter pattern
Why this matches the guide's deployment-matrix arc¶
The guide walks readers through Layer 0 (console) โ Layer 1 (FDM standalone) โ Layer 2 (SCC hybrid) โ Layer 3 (cdFMC). Every "return to zero" between those layers uses Ch 3.5 only โ fast, no download, deterministic. The one-time production handoff at the end of the arc runs Ch 3.5 + Ch 3.6 as a pair. Reset-only and reset+upgrade are the two operations the arc actually needs; giving each its own chapter matches how readers use the guide.
Meta-lesson for me¶
I flip-flopped twice on this decision (Candidate 2 initially, then Candidate 1 after Fabian pushed on lights-out robustness, then Candidate 3 after the workflow). The flip-flops all stemmed from optimizing for one property in isolation rather than treating "published SE playbook" as its own set of constraints. Ultracode's adversarial-verify pattern surfaced the trap โ a single lens (either "get to current patch" OR "no external deps") can look decisive until skeptics run at it. Both lenses need to fit the audience.
Live reset execution (~14:33-15:14) โ semantics I confabulated, semantics that are real¶
Fired the real reset. Two big semantic corrections and a wizard flow that's completely different from pre-7.6 platforms.
1. install security-pack version <same> force is a silent no-op on 1200-series 7.6.x¶
My earlier Ch 3.5 draft (based on the workflow's Candidate 1 verdict) said install security-pack version <pre-staged> force was the canonical reset. It isn't. Live-observed on the box:
firepower# scope firmware
firepower /firmware# scope auto-install
firepower /firmware/auto-install# install security-pack version 7.6.0-113 force
The system is currently installed with security software package 7.6.0-113, which has:
- The platform version: 2.16.0.128
- The CSP (ftd) version: 7.6.0.113
Do you want to proceed ? (yes/no): yes
Do you want to proceed? (yes/no): yes
Triggered the install of software package version 7.6.0-113
Force option: true
Install started. This will take several minutes.
30 minutes of silence later, show detail at /firmware/auto-install# revealed:
Firmware Auto-Install:
Package-Vers: 7.6.0-113
Oper State: Scheduled
Upgrade State: Update Software Pack Completed
Upgrade Status: upgraded
Firmware Upgrade Message: up-to-date โ the truth
force overrides cross-version compatibility warnings, not the same-version guard. The Force option: true line in the output is FXOS reporting your input; it doesn't mean anything for the same-version case.
Practical consequence: the "reset via pre-staged factory package" architecture that the workflow's Cisco-design lens praised and the SE-ops lens accepted-under-Candidate-3 doesn't work as a reset on this hardware unless pre-staged โ running. For factory-fresh 1210CE units where pre-staged = running (the common case), the operator MUST stage a different version before reset will actually reimage.
2. Cross-version install DOES reimage โ with a completely different output signature¶
Same command with a different target version:
firepower /firmware/auto-install# install security-pack version 7.6.4-69
The system is currently installed with security software package 7.6.0-113, which has:
- The platform version: 2.16.0.128
- The CSP (ftd) version: 7.6.0.113
If you proceed with the upgrade 7.6.4-69, it will do the following:
- upgrade to the new platform version 2.16.1.147
- reimage the system from CSP ftd version 7.6.0.113 to the CSP ftd version 7.6.4.69
During the upgrade, the system will be reboot
During the upgrade, the system will be reboot โ that phrase is only emitted on the cross-version code path. If you don't see it after two yes confirmations, the reset didn't fire.
3. New UUID as reimage evidence¶
Pre-reset FTD UUID: dc0bef0a-66b5-11f1-9951-911e3bad6766. Post-reset: 3c2bdc6c-7c8f-11f1-9ef7-9d09498b33b8. Different. A same-version-force pass would have kept the UUID (further evidence it doesn't actually reimage). Cross-version install regenerates the UUID โ Ch 4's verification checklist uses this as one of the three "did the reset actually run" checks.
4. Empirical timing on the reference reset (7.6.0-113 โ 7.6.4-69, 1210CE, 2026-07-10)¶
| Milestone | Wall-clock | ฮ from install fire |
|---|---|---|
install security-pack version 7.6.4-69 fired + yes ร 2 |
14:33:33 | 0 |
FTD shutdown sequence starts (INIT: Completed /etc/rc6.d/K00ftd.sh stop) |
14:34:31 | +57s |
| Mgmt IP dropped (192.168.10.59 โ 100% packet loss) | ~14:34:35 | +62s |
FXOS bundle-wipe fault emitted (Bundle version in firmware package is empty, need to re-install) |
14:37:35 | +4m 2s |
First firepower login: prompt reappears on console |
14:50:55 | +17m 21s |
FTD wizard Successfully performed firstboot initial configuration steps |
15:13:13 | +39m 40s |
At FTD > prompt with show version returning target |
~15:14 | +40m 30s |
My earlier "30-45 min" estimate was WebSearch summarizer output plus training-data extrapolation, not a directly-verified number for this SKU. Actual = ~17-18 min reimage + ~5 min wizard, total ~22-25 min end-to-end.
5. FTD 7.6.4 wizard flow โ minimal, and different from what my script assumed¶
The FTD setup wizard on 1200-series 7.6.4 doesn't run automatically at first boot. Sequence:
- FXOS-side first login โ
firepower login: admin/Password: Admin123โ forces password change on next line. - FXOS at
firepower#prompt โ FTD wizard has NOT yet run. connect ftdโ this is what triggers the FTD first-boot wizard.
The wizard itself (7.6.4) is much shorter than pre-7.6 flows. Live-captured prompts:
Please enter 'YES' or press <ENTER> to AGREE to the EULA:
Configure IPv4 via DHCP or manually? (dhcp/manual) [manual]:
Configure IPv6 via DHCP, router, or manually? (dhcp/router/manual) [dhcp]:
No DNS servers specified to configure.
No domain name specified to configure.
No hostname name specified to configure.
Setting DHCP for IPv4: management0
Manage the device locally? (yes/no) [yes]:
Configuring firewall mode to routed
Successfully performed firstboot initial configuration steps...
That's the whole wizard on 7.6.4. It does NOT prompt for hostname, DNS servers, search domains, proxy, or firewall mode โ those default to sensible values (hostname firepower, Cisco/OpenDNS resolvers, no proxy, routed mode). Custom values go through FDM UI in Ch 6 or the configure network FTD CLI commands.
My earlier reset script had wizard patterns for fully qualified hostname, DNS servers, search domains, proxy hostname, and firewall mode โ none of those prompts are ever emitted on this build. Script's pattern-matching worked by coincidence (matched adjacent text) and got lucky with defaults.
6. Ch 3.6 collapsed into Ch 3.5 after this run¶
The workflow's Candidate 3 architecture (two chapters โ reset + upgrade separately) was based on the assumption that reset and upgrade are semantically distinct operations. On 1200-series 7.6.x, they're the SAME FXOS command with different version targets. Two chapters was documenting an architectural split that doesn't exist on this hardware. Collapsed:
- Ch 3.5 (rewritten) โ the reset mechanism as it actually works: cross-version install. Includes the package-staging sub-section (previously Ch 3.6) as optional, only needed if the operator doesn't already have a suitable target on flash.
- Ch 3.6 โ DELETED. mkdocs.yml nav updated, troubleshooting.md updated to point at only Ch 3.5.
The workflow's residual value: the decision gate language (production-readiness) and the change-record hygiene section moved into Ch 3.5's tail. The two-chapter split itself was a false architecture given the hardware's actual behavior.
7. Watchdog pattern that kept failing¶
Every wrapper watchdog I set up followed this pattern:
until ! kill -0 $PID 2>/dev/null; do sleep 30; done
echo "SCRIPT-EXITED $(date -Iseconds)"
tail -80 $LOG
Some watchdogs completed with exit 0 (log intact when tail ran). Two completed with exit 1 because I renamed the log file mid-flight and tail couldn't find it. The reliable pattern going forward: launch the actual pexpect script under Bash run_in_background: true โ the harness watches the script's PID directly, notifies me on exit with the script's stdout, no wrapper needed. Post-run redaction happens inside the pexpect script itself so the log is publication-safe when the task-notification fires.