This post will describe something interesting that happens to traceroute
when you are doing NAT. The inspiration for this post came from a
thread at IEOC started by Nick O’neill. He was doing ip nat outside translation but I
have found that the same behavior is true also for inside translations.

We will use this topology:


R1 has a loopback on the inside. On the outside this will be known as You can see the networks connecting the routers are, and R3 will be the router doing NAT and this is the
configuration of it:

interface FastEthernet0/0
 ip address
 ip nat inside
interface FastEthernet0/1
 ip address
 ip nat outside
ip route
ip nat inside source static

This is not a post describing the basics but make sure that you have routing setup.
I am using static routing here. When doing static NAT like this there is bidirectional
communication setup. Remember that when the outside to inside translation is done NAT
is performed before the routing lookup so we must have a route to on R3.

The command above translates the inside local address to an inside global address.
R4 will traceroute to and we will see what happens.

R4#traceroute num prob 1

Type escape sequence to abort.
Tracing the route to

  1 28 msec
  2 124 msec
  3 84 msec

Interesting. Hops 2 and 3 are the same and they have the inside global address as source.
What happened here? The first hop is correct. The ICMP TTL exceeded should come back from
the outgoing interface used to reach which was the source of the UDP traceroute
packet sent. Hop 2 should have been

If we compare it to MPLS this almost looks like some core hiding feature as it does not
reveal the internal addressing of our network. If we look at debug on R3 we will see
what is happening.

R3# debug ip nat det
IP NAT detailed debugging is on
NAT: i: icmp (, 33435) -> (, 49164) [1]  
NAT: s=>, d= [1]
NAT: i: icmp (, 33436) -> (, 49165) [2]  
NAT: s=>, d= [2]

We clearly see that the inside addresses are being translated to
even though there is no matching NAT statement. The number 33435 is the source
port number and 49164 is the destination port number.

This is the IOS version used for this lab:

R3#sh ver | i IOS
Cisco IOS Software, 3700 Software (C3725-ADVENTERPRISEK9-M), Version 12.4(15)T10, RELEASE SOFTWARE (fc3)

Now if we try it on mainline IOS instead…

R3#sh ver | i IOS
Cisco IOS Software, 3700 Software (C3725-ADVIPSERVICESK9-M), Version 12.4(25d), RELEASE SOFTWARE (fc1)
R4#trace num prob 1

Type escape sequence to abort.
Tracing the route to

  1 68 msec
  2 164 msec
  3 196 msec

As you can see with the mainline IOS we can see the real addresses as they are not
being translated.

Knowing me you know that I like to dig deep to find out what is going on. I reached
out to a contact at Cisco to see if he could find any reference to what is happening
here. It turns out that this is related to bug CSCsu37097. Basically the customer
didn’t want the internal addressing revealed and so this was incorporated into IOS.
The symptom was described as: “Symptom:
Traceroute/ICMP unreachable doesn’t translate properly and can cause security problem.”

The following quote is also available from Cisco: “In Cisco IOS Release 15.1(3)T and
later releases, when you configure the traceroute command, NAT returns the same
inside global IP address for all inside local IP addresses.”
The source is this

So basically this was implemented as a security feature for NAT. I hope you
learned something interesting.

NAT translation – What happened to my traceroute?
Tagged on:                         

5 thoughts on “NAT translation – What happened to my traceroute?

  • May 29, 2013 at 1:32 pm

    Very interesting Daniel, nice find!

  • May 29, 2013 at 9:26 pm

    Great post! Hope you write some more articles about these kind of bugs/errors. 🙂 debug/facts about how stuff works is frikkin awesome. 🙂

  • August 21, 2014 at 6:50 pm

    I surely learnt something interesting after reading this. Thanks! I was doing some troubleshooting on a lab using similar IOS version (C3725-ADVENTERPRISEK9-M), Version 12.4(15)T14) and ran into the same challenge with the translated addresses and ICMP replies. In my case there were no replies after the first hop. I ended using a different IOS and was able to see the translations and ICMP replies as expected… what a mind job!


Leave a Reply

Your email address will not be published. Required fields are marked *