
A partner API starts rejecting connections just after a NAT change. The server's published address, 10.42.20.5, still answers inbound HTTP. An inside client still reaches the external HTTP service through PAT. Even packet-tracer says allow. The broken request is the server's outbound connection to the partner.
I built this in my home lab with FMCv 10.0.1, FTDv 10.0.0 and an IOL router in Containerlab. The partner accepts TCP/8443 only from 10.42.20.5. Putting a broad manual interface PAT rule in NAT Rules Before changed the server's outbound source to 10.42.20.1. The partner returned a TCP reset. Recreating the equivalent PAT rule in NAT Rules After restored source 10.42.20.5 and HTTP 200.
That is the FTD NAT order problem here: a matching Section 1 rule takes the outbound flow before the server's Section 2 static Auto NAT rule gets a chance. The static mapping remains configured and still works for the tested inbound request.
This is a nested home lab, not a supported production deployment. The evidence below comes from the recorded baseline, fault and repair on these builds.
Topology and addressing
client-a and web-in share an inside switch. FTD connects that subnet to r-core, which leads to ext-host. FMC manages FTD over the management tunnel; that path is separate from the traffic being translated here.
| Node or interface | Address | Purpose |
|---|---|---|
| client-a | 10.42.10.21/24 | Inside client; external HTTP control test |
| web-in | 10.42.10.80/24 | Inside web server; static NAT to 10.42.20.5; outbound partner caller |
| FTD Ethernet0/0, inside | 10.42.10.1/24 | Zone PL-INSIDE |
| FTD Ethernet0/1, outside | 10.42.20.1/29 | Zone PL-OUTSIDE; interface PAT address |
| r-core Ethernet0/1 | 10.42.20.2/29 | Next hop from FTD toward ext-host |
| r-core Ethernet0/2 | 10.42.30.1/24 | Gateway on the external server subnet |
| ext-host | 10.42.30.80/24 | TCP/80 open; partner TCP/8443 accepts only source 10.42.20.5 |
| FMCv | Management tunnel | Configures FTD; outside this data path |
FTD has a route to 10.42.30.0/24 through outside next hop 10.42.20.2. The endpoints route the relevant data subnets through their local data gateways. r-core's saved startup configuration has no route to 10.42.10.0/24. The successful external requests therefore do not depend on routing the untranslated inside source back through r-core.
The address called “public” in this lab is 10.42.20.5 on the outside segment. It is a private lab address, not an internet-routable allocation. Likewise, client “internet PAT” is tested against ext-host TCP/80, not a public internet service. TCP/8443 deliberately carries plain HTTP here; this is a source allow-list test, not a TLS test.
The automatic registration deployment failed without a reason exposed in this session; a subsequent normal baseline deployment succeeded. Registration itself is covered in registering FTDv to FMC. For the separate routing fault, see an FTD static route with a dead next hop.
How FMC's NAT sections map to FTD
On FMC 10.0.1, I opened Policies > Network policies > NAT. PL-Edge-NAT contained three section headers. The diagnostic CLI uses different names for those same sections:
| FMC section | FTD show nat detail heading | Role in this lab |
|---|---|---|
| NAT Rules Before | Manual NAT Policies (Section 1) | Broad PAT wins here during the fault |
| Auto NAT Rules | Auto NAT Policies (Section 2) | Server's static .80-to-.5 mapping |
| NAT Rules After | Manual NAT Policies (Section 3) | Broad PAT is the fallback in the working states |
For this outbound flow, FTD checks the earlier manual section before Auto NAT, then the later manual section if needed. The server belongs to PL-INSIDE-NET, so the broad PAT rule can match it as well as client-a. Placing that rule before Auto NAT gives it priority over the server's static mapping.
“Static” does not mean “wins over every dynamic rule.” The section matters first. With broad PAT after Auto NAT, web-in gets its static source address and client-a falls through to interface PAT. With broad PAT before Auto NAT, both use interface PAT for these outbound tests.
This experiment has one Auto NAT rule; it does not test tie-breaking among several Auto NAT entries. The related ASA NAT order walkthrough and ASA NAT table sections and priority provide more background, but the section headers and selected translations below establish what this FTD actually did.
Baseline FTD NAT configuration: static Auto NAT, then PAT
I created three network objects: PL-INSIDE-NET for 10.42.10.0/24, PL-WEB-IN for 10.42.10.80, and PL-WEB-IN-PUB for 10.42.20.5. In PL-Edge-NAT, assigned to the FTD device, the server rule used Auto NAT Rule, Static, source interface object PL-INSIDE and destination interface object PL-OUTSIDE. Its original source was PL-WEB-IN and its translated source was PL-WEB-IN-PUB.
The second rule used Manual NAT Rule, Dynamic, and Insert > In Category > NAT Rules After. It used the same interface objects, original source PL-INSIDE-NET, and translated source Destination Interface IP. That field selects FTD's outside interface address in this rule; it does not mean the partner's destination address.

After adding both rules, the policy view showed an empty Before section, the static Auto NAT rule, and broad dynamic interface PAT in After.

The access policy retained Allow-ICMP and Allow-Web, and included Allow-Partner-API from web-in to ext-host TCP/8443. Allow-Web-In permitted outside HTTP to the real server address, 10.42.10.80. The default action remained Block All Traffic. End logging to FMC was enabled for the relevant web and partner rules. NAT and permission were separate checks; the FTD access-control lab covers that policy side in FDM.
I saved and deployed the baseline before testing traffic. On FTD, the diagnostic CLI's show nat detail placed the rules in Sections 2 and 3. Excerpt from the baseline readback:
> show nat detail
show nat detail
Auto NAT Policies (Section 2)
1 (inside) to (outside) source static PL-WEB-IN PL-WEB-IN-PUB
translate_hits = 1, untranslate_hits = 1
Source - Origin: 10.42.10.80/32, Translated: 10.42.20.5/32
Manual NAT Policies (Section 3)
1 (inside) to (outside) source dynamic PL-INSIDE-NET interface
translate_hits = 1, untranslate_hits = 0
Source - Origin: 10.42.10.0/24, Translated: 10.42.20.1/29
The deployed NAT configuration also included the after-auto keyword on the broad rule. This is readback from FMC's deployment, not a configuration change made locally on FTD:
> show running-config nat
show running-config nat
!
object network PL-WEB-IN
nat (inside,outside) static PL-WEB-IN-PUB
!
nat (inside,outside) after-auto source dynamic PL-INSIDE-NET interface
All three baseline checks returned HTTP 200: client-a to ext-host TCP/80, web-in to partner TCP/8443, and ext-host to published 10.42.20.5 TCP/80. The partner response from web-in was:
PL-partner-api
HTTP=200
The capture on ext-host's data interface recorded the real API request leaving as 10.42.20.5, source port 45284:
2026-10-19 17:57:32.666658 IP 10.42.20.5.45284 > 10.42.30.80.8443: Flags [S], seq 3840272020, win 56760, options [mss 1380,sackOK,TS val 2441007240 ecr 0,nop,wscale 10], length 0
That baseline matters. It establishes that the partner listener, source allow-list, routing and access policy could support this request before changing the NAT section.
The fault: put the broad PAT rule before Auto NAT
The fault used an equivalent broad Manual Dynamic PAT rule in NAT Rules Before. Its source network, interface objects and translated source stayed equivalent to the working rule. The static Auto NAT rule stayed unchanged. I saved and deployed this policy before repeating the same endpoint tests.

The results split by flow:
| Test | Baseline: PAT After | Fault: PAT Before | Fixed: PAT After |
|---|---|---|---|
| client-a to ext-host TCP/80 | HTTP 200, source .1 | HTTP 200, source .1 | HTTP 200, source .1 |
| web-in to partner TCP/8443 | HTTP 200, source .5 | curl exit 7, source .1 | HTTP 200, source .5 |
| ext-host to 10.42.20.5 TCP/80 | HTTP 200 | HTTP 200 | HTTP 200 |
Here .1 and .5 mean 10.42.20.1 and 10.42.20.5. The failed partner request from web-in produced this recorded output:
HTTP=000
curl: (7) Failed to connect to 10.42.30.80:8443 after 5 ms: Could not connect to server
Exit 7
HTTP 000 is curl's reported status when it did not receive an HTTP response. It is not a response code sent by the partner. The packet capture explains the failed connection more precisely than that application symptom alone.
The control requests still succeeded in that same fault state. client-a's external HTTP response was:
PL-ext-80
HTTP=200
The inbound request from ext-host to 10.42.20.5 returned the inside server's response:
PL-web-in
HTTP=200
FMC 10.0.1: the section change required recreation
I could not move the existing rule between these sections through Edit NAT Rule in this session. The Insert/category control was disabled. The bulk menu offered only Enable, Disable and Delete, and dragging the rule toward the other section did not move it.

For both the fault and the repair, I deleted the existing manual PAT rule and recreated an equivalent rule through Add Rule, choosing the required category there. This was not a successful edit-in-place or drag move. The comparison is between equivalent match and translation settings in different sections. These are observations from this FMC build, not a claim about every release's rule editor.
The partner capture shows the wrong source and a reset
On ext-host, tcpdump captured the failing request on the data interface. These two consecutive lines are the real API flow with source port 56496:
2026-10-19 18:01:56.579989 IP 10.42.20.1.56496 > 10.42.30.80.8443: Flags [S], seq 2180771156, win 56760, options [mss 1380,sackOK,TS val 1837733919 ecr 0,nop,wscale 10], length 0
2026-10-19 18:01:56.580121 IP 10.42.30.80.8443 > 10.42.20.1.56496: Flags [R.], seq 0, ack 2180771157, win 0, length 0
The SYN arrived from 10.42.20.1, not the allow-listed 10.42.20.5. ext-host immediately sent RST/ACK back to that source. The partner's INPUT rules accepted .5 on TCP/8443 and rejected other sources with tcp-reset; the fault snapshot showed one rejected packet:
pkts bytes target prot opt in out source destination
5 348 ACCEPT tcp -- * * 10.42.20.5 0.0.0.0/0 tcp dpt:8443
1 60 REJECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8443 reject-with tcp-reset
Together, the known allow-list and destination-side capture explain the failure. FTD forwarded a packet whose translated identity the partner rejected. Opening the FTD access rule further would not restore the required source address.
The capture point also matters: ext-host sees the address that arrived after FTD's translation. An inside-only capture would show web-in's real source and leave this part of the diagnosis unanswered. The FTD packet-tracer and capture lab follows a different failure where an allowed simulation still needs packet evidence.
NAT counters identify the winning rule
To isolate the outbound match, I took a show nat detail snapshot, sent three more partner requests from web-in, then took another snapshot. No inbound test or packet-tracer simulation occurred between those two reads.
Before the three requests:
> show nat detail
show nat detail
Manual NAT Policies (Section 1)
1 (inside) to (outside) source dynamic PL-INSIDE-NET interface
translate_hits = 3, untranslate_hits = 0
Source - Origin: 10.42.10.0/24, Translated: 10.42.20.1/29
Auto NAT Policies (Section 2)
1 (inside) to (outside) source static PL-WEB-IN PL-WEB-IN-PUB
translate_hits = 2, untranslate_hits = 2
Source - Origin: 10.42.10.80/32, Translated: 10.42.20.5/32
After the three requests:
> show nat detail
show nat detail
Manual NAT Policies (Section 1)
1 (inside) to (outside) source dynamic PL-INSIDE-NET interface
translate_hits = 6, untranslate_hits = 0
Source - Origin: 10.42.10.0/24, Translated: 10.42.20.1/29
Auto NAT Policies (Section 2)
1 (inside) to (outside) source static PL-WEB-IN PL-WEB-IN-PUB
translate_hits = 2, untranslate_hits = 2
Source - Origin: 10.42.10.80/32, Translated: 10.42.20.5/32
The manual rule's translate_hits rose from 3 to 6. The static rule stayed at translate_hits 2 and untranslate_hits 2. All three extra requests failed. The earlier manual rule received the outbound translations while the static rule's counters did not move.
Those are deliberately paired snapshots. Other reads include separate tests and simulations, so subtracting arbitrary counters elsewhere in the session would mix traffic. A rising counter identifies a rule match; it does not prove that the application completed successfully.
The translation table corroborates PAT to .1
The failed API connection reset too quickly to retain its individual translation for inspection. To make the runtime PAT entry visible, I held a separate, allowed TCP/80 flow from web-in using source port 40580. The show xlate excerpt contained both the server's static mapping and that live PAT entry:
NAT from inside:10.42.10.80 to outside:10.42.20.5
flags s idle 0:00:37 timeout 0:00:00
...
TCP PAT from inside:10.42.10.80/40580 to outside:10.42.20.1/40580 flags ri idle 0:00:03 timeout 0:00:00
The 40580 entry is evidence of web-in using interface PAT during the fault. It is not the failed API request. Its coexistence with the static entry also shows why finding the .5 mapping in show xlate was insufficient: another outbound flow from that same server was actively translated to .1.
Packet-tracer allows the wrong translation
On FTD, I used system support diagnostic-cli for the NAT readbacks and packet-tracer. The CLI simulation tested inside TCP from 10.42.10.80:40500 to 10.42.30.80:8443. Its fault NAT phase selected the manual rule and translated the source to .1:
> packet-tracer input inside tcp 10.42.10.80 40500 10.42.30.80 8443 detail
...
Phase: 5
Type: NAT
Subtype:
Result: ALLOW
Elapsed time: 472 ns
Config:
nat (inside,outside) source dynamic PL-INSIDE-NET interface
Additional Information:
Dynamic translate 10.42.10.80/40500 to 10.42.20.1/40500
...
Action: allow
The overall result was allow. That verdict describes FTD's simulated handling; it cannot certify the partner's source allow-list. For readers coming from ASA, the same habit of checking the selected NAT phase is useful in Cisco ASA packet-tracer.
In FMC, I opened Troubleshooting > Tools > Packet Tracer, selected the device and inside interface, and traced the same hosts and destination port with source port 40501. Expanding NAT and Additional Information showed dynamic translation to 10.42.20.1 while the trace result remained ALLOW.

This run retained the default prefilter policy. It was not the prefilter Fastpath case that skips ACP evaluation; the real fault event identified Allow-Partner-API. The mismatch was the translated source accepted by the destination.
Unified Events confirms the real request's NAT source
In Events & Logs > Analysis > Unified Events, I refreshed Last 1 hour and included Action, real source and destination tuples, and NAT Source IP. The fault API event used real source port 56496, action Allow, rule Allow-Partner-API, and NAT Source IP 10.42.20.1.

That historical event was expanded after the fix to read its completed details. It remains evidence of the earlier fault, not a fresh failed test. The Unified Events display clock was UTC-4; packet-capture timestamps were UTC. Matching the tuple is safer than assuming the screens use the same clock.
The real partner request ports were 45284 in the baseline, 56496 during the fault and 38714 after repair. Ports 40500–40502 belong to packet-tracer simulations. Port 40580 belongs to the held HTTP flow. Keeping those identities separate prevents an allowed simulation from becoming supposed proof of a successful real API call.
Why inbound HTTP still worked
During the fault, ext-host still received PL-web-in and HTTP 200 when requesting 10.42.20.5 TCP/80. The static Auto NAT rule remained installed, its .5 translation remained visible, and the inbound test continued to reach the server. Meanwhile, server-originated partner traffic used the Section 1 broad PAT rule.
That is the directional result this lab demonstrated. It does not establish that every inbound protocol or every overlapping NAT policy would behave the same way. The working inbound check simply failed to detect this outbound source change.
The stale manual ASA NAT lab fails on the inbound publish side: an earlier manual static rule selects the wrong backend. Here, the earlier manual rule changes the outbound source, and the destination rejects it. Both investigations need the selected translation, not just confirmation that a static rule exists.

Fix: recreate broad PAT in NAT Rules After
I deleted the Before manual PAT rule and added the equivalent Dynamic rule in NAT Rules After, retaining PL-INSIDE-NET, PL-INSIDE to PL-OUTSIDE, and Destination Interface IP. The static Auto NAT rule stayed untouched. After saving, I deployed the corrected policy and waited for completion.

The fixed show nat detail readback restored the Section 2/3 arrangement:
> show nat detail
show nat detail
Auto NAT Policies (Section 2)
1 (inside) to (outside) source static PL-WEB-IN PL-WEB-IN-PUB
translate_hits = 3, untranslate_hits = 3
Source - Origin: 10.42.10.80/32, Translated: 10.42.20.5/32
Manual NAT Policies (Section 3)
1 (inside) to (outside) source dynamic PL-INSIDE-NET interface
translate_hits = 1, untranslate_hits = 0
Source - Origin: 10.42.10.0/24, Translated: 10.42.20.1/29
The fresh CLI simulation selected the server's static mapping:
> packet-tracer input inside tcp 10.42.10.80 40500 10.42.30.80 8443 detail
...
Phase: 5
Type: NAT
Subtype:
Result: ALLOW
Elapsed time: 394 ns
Config:
object network PL-WEB-IN
nat (inside,outside) static PL-WEB-IN-PUB
Additional Information:
Static translate 10.42.10.80/40500 to 10.42.20.5/40500
...
Action: allow
A new GUI trace used source port 40502 and likewise showed static translation to .5:

Then I repeated the real requests. web-in's partner call returned:
PL-partner-api
HTTP=200
The external capture recorded the fresh API connection as source 10.42.20.5:38714 and the partner's SYN/ACK:
2026-10-19 18:05:27.939786 IP 10.42.20.5.38714 > 10.42.30.80.8443: Flags [S], seq 2573724640, win 56760, options [mss 1380,sackOK,TS val 3874406318 ecr 0,nop,wscale 10], length 0
2026-10-19 18:05:27.939982 IP 10.42.30.80.8443 > 10.42.20.5.38714: Flags [S.], seq 339052255, ack 2573724641, win 56688, options [mss 9460,sackOK,TS val 3737541743 ecr 3874406318,nop,wscale 10], length 0
client-a's external HTTP test and inbound HTTP to .5 both returned 200 again. Unified Events showed the real fixed request on port 38714 translated to .5 alongside the historical failed requests translated to .1.

The repair corrected the section and verified the new connections. For broader policy changes, FMC Deployment History and rollback covers a separate recovery workflow. If moving this policy from ASA, carry the intended rule precedence into the review as well as the addresses; the ASA-to-FTD migration lab is related reading.
Verification checklist
- Confirm the intended source at the destination: web-in must arrive as 10.42.20.5, while client-a may use 10.42.20.1.
- Read all three FMC sections. In this policy, Before is empty, the server static is Auto NAT, and broad PAT is After.
- Check deployed show nat detail output for Sections 2 and 3; do not rely only on the saved policy view.
- Compare counters around an isolated request set. Keep inbound tests and simulations outside that measurement window.
- Inspect the NAT phase and translated address even when packet-tracer reports ALLOW.
- Match the real request's source port to Unified Events and NAT Source IP. Account for the display clock.
- Verify real partner HTTP 200, client PAT HTTP 200 and inbound publish HTTP 200 after deployment.
- On this FMC build, confirm the final section after recreating a rule; editing and dragging did not move it in this session.
Related firewall labs
- Register FTDv to FMC — A mismatched registration key prevents the management tunnel from completing.
- FTD static route in FMC — Trace a forwarding failure to a dead next hop.
- FMC prefilter Fastpath — See how Fastpath skips access-control policy evaluation.
- FTD packet-tracer and capture — Follow an allowed simulation with capture evidence when no SYN-ACK returns.
- FMC Deployment History and rollback — Work through a separate deployment recovery lab.
- Stale manual ASA NAT — Compare this outbound source fault with an earlier rule shadowing an inbound publish.
- Cisco FTD twice NAT in FMC — Swapped Original and Translated Destination objects break both the old and new partner addresses.
FAQ
Does static Auto NAT always beat manual dynamic PAT?
No. In this lab, broad manual dynamic PAT in NAT Rules Before matched web-in before its static Auto NAT rule. Putting equivalent PAT in NAT Rules After let the static mapping provide the server's outbound source.
Why did packet-tracer allow a request that curl could not connect to?
FTD allowed and translated the flow, but used 10.42.20.1. The partner accepted only 10.42.20.5 and returned a TCP reset. The simulation's allow result did not prove acceptance by that external allow-list.
Is FTD static NAT not working if outbound calls use the wrong IP?
That symptom alone does not show that the static mapping is missing. Inbound HTTP to .5 worked here and the static translation remained present. The outbound partner flow nevertheless matched earlier PAT. Verify the source seen by the partner rather than using an inbound test as proof of outbound identity.
Where did I configure the FMC NAT policy on 10.0.1?
Under Policies > Network policies > NAT. Add Rule allowed selection of NAT Rules Before or NAT Rules After for the manual rule. In this session, Edit NAT Rule disabled that category field, so changing sections required deleting and recreating the equivalent rule.
What is the difference between NAT Rules Before and NAT Rules After in FMC?
NAT Rules Before appears in FTD's show nat detail as Manual NAT Policies (Section 1) and is checked before Auto NAT Rules (Section 2). NAT Rules After is Manual NAT Policies (Section 3), used only when nothing earlier matches; FMC deploys it with the after-auto keyword. In this lab, broad PAT in Before took web-in's outbound flow; in After, web-in kept its static 10.42.20.5 and client-a fell through to interface PAT.