ICMP has no port number. It is an IP-layer protocol, number 1 in the IP header, that sits beside TCP and UDP rather than on top of them, so ping does not use a port and there is no "ping port" to open. When a firewall form asks for one, select the ICMP protocol and the echo request type instead. This post covers where ICMP sits in the stack, which types and codes you will actually meet, how to allow it through Linux, Windows and cloud firewalls, and when a ping check is the wrong check.

Quick summary

  • ICMP is IP protocol 1 (RFC 792), TCP is protocol 6, UDP is protocol 17. Only the last two carry port numbers.
  • ping sends ICMP type 8 (echo request) and expects type 0 (echo reply). Firewall rules match on type and code, never on a port.
  • ICMPv6 is next-header 58 and carries neighbor discovery (types 133 to 136). Blocking it entirely breaks IPv6 on the link.
  • Linux traceroute sends UDP to ports 33434 and up by default, traceroute -I uses ICMP echo, Windows tracert uses ICMP echo only. Every variant needs ICMP type 11 replies from the hops.
  • A ping monitor proves the host answers ICMP, a TCP port monitor proves a service is listening on 443, 22 or 5432, an HTTP monitor proves it works. Most services need the last two.

Why do people search for an ICMP port number?

Almost every search for "icmp port" or "ping port number" starts at a firewall. Security group and firewall forms are built around TCP and UDP, so they show a port field, and the person filling it in assumes ping must have one. "Please open the ping port to 10.0.2.15" is a ticket I have seen more than once.

Tooling that calls a TCP connect a ping adds to the confusion. tcping host 443, PowerShell's Test-NetConnection host -Port 443 and nc -zv host 443 report up or down like ping does, but they open a TCP connection to a real port. Plain ping, Test-NetConnection without -Port, and any monitor labelled ICMP send echo requests and use no port at all.

Does ICMP use a port? Where it sits next to TCP and UDP

An IP packet carries a protocol field that says what comes next: 6 means a TCP segment, 17 a UDP datagram, 1 an ICMP message. TCP and UDP headers each contain a source and destination port so the receiving host can hand the payload to the right socket. An ICMP header contains a type, a code and a checksum, and the kernel processes it directly, so there is no socket and no port to name.

Protocol Layer Uses ports? Typical check
ICMP (protocol 1) Internet, inside IP No, type and code instead ping host, ICMP monitor
ICMPv6 (next header 58) Internet, inside IPv6 No, type and code instead ping -6 host
TCP (protocol 6) Transport, on top of IP Yes, 0 to 65535 nc -zv host 443, TCP port monitor
UDP (protocol 17) Transport, on top of IP Yes, 0 to 65535 dig @host, nc -zvu host 53
HTTP/HTTPS Application, on top of TCP Inherits 80 or 443 curl -I https://host, HTTP monitor

This is why an "All ICMP - IPv4" rule in AWS or --allow icmp in GCP has no port argument: the rule matches on the protocol number in the IP header, optionally narrowed by type and code.

Which ICMP types and codes will you actually meet?

RFC 792 defines a few dozen combinations, but day to day you will meet these six in firewall logs and tcpdump captures.

Type Code Name When you see it
8 0 Echo request Every ping, and every ICMP monitor check
0 0 Echo reply The answer to a ping, so the host is up and ICMP is allowed
3 3 Destination unreachable, port unreachable UDP sent to a closed port, and the final hop of a UDP traceroute
3 13 Destination unreachable, administratively prohibited A firewall configured to reject rather than drop
3 4 Fragmentation needed and DF set Path MTU discovery; blocking this stalls large TLS transfers
11 0 Time exceeded, TTL exceeded in transit Every intermediate hop in a traceroute

Two of these cause failures that do not look like ICMP problems. Type 3 code 4 is how a host learns that a link on the path has a smaller MTU, so a firewall that drops all ICMP breaks large downloads and VPN traffic while small requests keep working. Type 11 is what makes traceroute possible. A firewall that drops rather than rejects produces none of these messages, which is why a blocked ping and a powered-off host look identical from outside: both time out.

How to allow ICMP through a firewall

The rule you need is always "inbound, protocol ICMP, type echo request", from the source ranges that should reach the host. Work from the inside out, because a correct rule at the cloud layer does nothing if the host kernel drops the packet.

1. Check that the host itself answers ping

On Linux, a value of 1 here means echo requests are ignored regardless of any iptables or nftables rule.

$ sysctl net.ipv4.icmp_echo_ignore_all
net.ipv4.icmp_echo_ignore_all = 0

Then ping from a machine on the same subnet. If that works and a ping from outside does not, the problem is a firewall on the path.

2. Allow ICMP echo requests on the host firewall

On Linux with iptables, or with nftables (adjust the table and chain names to your ruleset):

sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
sudo nft add rule inet filter input icmp type echo-request accept

ufw allows echo requests by default through /etc/ufw/before.rules, and firewalld allows them in its default zones, so on those systems the host firewall is rarely the culprit.

Windows Firewall drops inbound echo requests unless a rule allows them, which is why a fresh Windows machine does not answer ping. Add a rule with either command from an administrator prompt:

netsh advfirewall firewall add rule name="ICMPv4 echo request in" protocol=icmpv4:8,any dir=in action=allow
New-NetFirewallRule -DisplayName "ICMPv4 echo request in" -Protocol ICMPv4 -IcmpType 8 -Direction Inbound -Action Allow

The icmpv4:8,any part is the type and code. That is the ICMP equivalent of a port field.

3. Allow ICMP at the cloud or network layer

Cloud firewalls sit in front of the instance and default to deny inbound. In the AWS console the rule type is All ICMP - IPv4, or Custom ICMP - IPv4 with Echo Request to be narrow. From the CLI:

aws ec2 authorize-security-group-ingress --group-id sg-0123456789abcdef0 --protocol icmp --port -1 --cidr 203.0.113.0/24
gcloud compute firewall-rules create allow-ping --network default --allow icmp --source-ranges 203.0.113.0/24
az network nsg rule create -g myRG --nsg-name myNSG -n AllowICMP --priority 300 --direction Inbound --access Allow --protocol Icmp --source-address-prefixes 203.0.113.0/24

--port -1 in the AWS command means all ICMP types and codes, since the port argument carries type and code for this protocol. GCP's default network already ships with a default-allow-icmp rule; custom networks do not. On AWS, a network ACL on the subnet also has to allow ICMP in both directions, because ACLs are stateless.

4. Verify from outside and keep it verified

Ping the public address from a machine outside the network, then add an ICMP monitor that repeats the check from several regions, so the next person who tightens a security group hears about it before your users do. Hyperping's ping and TCP port monitors confirm a failure from other regions before alerting, which filters out one region losing its route.

What about ICMPv6?

ICMPv6 is next-header 58, defined in RFC 4443, and it does more than diagnostics. Neighbor discovery, the IPv6 replacement for ARP, runs over ICMPv6 types 133 to 136, path MTU discovery uses type 2 (packet too big), and echo request and reply are types 128 and 129.

A firewall that drops all ICMPv6 stops the host from resolving its neighbours' link-layer addresses, so IPv6 fails in ways that look nothing like a ping problem. RFC 4890 lists the types that must pass; at minimum allow types 1 to 4 and 133 to 136:

sudo nft add rule inet filter input icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, echo-request } accept

Which protocol does traceroute use?

Traceroute sends probes with a TTL of 1, then 2, then 3, and reads the ICMP time exceeded (type 11) message each hop returns. What differs between tools is the probe itself:

  • Linux and macOS traceroute send UDP datagrams to destination ports starting at 33434 and incrementing per probe. The final hop answers with ICMP type 3 code 3, port unreachable.
  • traceroute -I and mtr send ICMP echo requests, and the final hop answers with an echo reply.
  • traceroute -T sends TCP SYN, to port 80 by default. Use -T -p 443 to trace what an HTTPS client would see.
  • Windows tracert sends ICMP echo requests only.

Blocking outbound UDP above 33434 breaks the default Linux traceroute but not tracert, and blocking inbound ICMP type 11 turns every hop into * * * for all of them. When a host looks unreachable, traceroute -T -p 443 comes closest to the path an HTTPS client takes.

Ping vs port vs HTTP monitoring: which check answers which question?

I run Hyperping, which offers all three check types, so read this with that in mind. The advice holds whichever tool you use: each check answers one question, and the mistake is picking a check that answers a question you do not care about.

Check What it proves What it misses Use it for
Ping (ICMP echo) The host is powered on, routed and allowed to answer ICMP A crashed service, a full disk, a firewall that only allows ICMP Routers, VPN gateways, appliances, bare hosts
TCP port (connect on 443, 22, 5432, 6379) A process is listening and the path allows that port An application that accepts connections and returns errors Databases, SSH, mail, caches, anything without HTTP
HTTP or HTTPS The application returns the expected status, body and TLS certificate Nothing about hosts that do not speak HTTP Websites, APIs, health endpoints

A ping check is right when the host itself is what you care about, or when the service does not accept connections from outside. It is wrong as the only check on a web server: a box can answer ping for hours while nginx is down. Some networks filter ICMP altogether, and a ping monitor on such a host reports it down while everything works, a false alarm you fix by monitoring a port instead. The same reasoning applies to cutting false positive alerts in general: check the thing users depend on.

For a database or a mail server, a TCP connect on 5432 or 587 tests what clients do. For anything with an HTTP surface, an uptime monitor that requests the health endpoint and asserts on the response gives you response time as well as the up or down bit, and what counts as a good API response time is a question only HTTP checks can answer. If you are chasing packet loss or a saturated link, ICMP round trips only hint at it; interface counters on the host, covered in how to monitor network throughput on Linux, tell you more.

The short version, for the person who arrived here from a firewall form: there is no port. Select ICMP, allow echo request, verify from outside, and monitor the port your service actually listens on.