{"id":1452,"date":"2026-10-20T22:37:36","date_gmt":"2026-10-20T22:37:36","guid":{"rendered":"https:\/\/virtualserversvps.com\/blog\/?p=1452"},"modified":"2026-10-20T22:37:36","modified_gmt":"2026-10-20T22:37:36","slug":"mtu-pmtud-black-hole-troubleshooting","status":"publish","type":"post","link":"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/","title":{"rendered":"MTU and PMTUD Black Holes: Diagnosing the Stalls That Look Like TLS Failures"},"content":{"rendered":"<div style=\"padding:20px\">\n<p>Most TLS failures that are not certificate errors are MTU problems wearing a disguise. The TCP handshake completes, the certificate verifies, the first small HTTP response arrives \u2014 and then the transfer hangs the moment a large record is sent. The cause is Path MTU Discovery failing somewhere between client and server, so the server keeps transmitting full-size segments that are silently dropped, retried, and dropped again. This guide shows how to confirm a PMTUD black hole with a two-minute test, how to size MSS clamping on a tunnel or overlay, and how to verify the fix with <code>tcpdump<\/code> and per-socket counters. It assumes a Linux instance, run on <a href=\"https:\/\/virtualserversvps.com\/\">a provider network where you control the guest but not every hop<\/a>.<\/p>\n<h2>The Failure Signature<\/h2>\n<p>Recognise it by shape rather than by any single error message:<\/p>\n<ul>\n<li>Small responses succeed (<code>curl -I<\/code> works), large ones stall or take exactly 30 seconds \u2014 the kernel&#8217;s MSS retry ladder.<\/li>\n<li>The connection establishes, TLS handshake completes with a small certificate chain, then the body never arrives.<\/li>\n<li><code>ss -ti<\/code> shows a socket with a small <code>cwnd<\/code>, non-zero retransmits and <code>unacked<\/code> stuck at 1\u20133.<\/li>\n<li>The same client works fine to other servers, and the problem correlates with VPN, PPPoE, or a mobile carrier.<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>&lt;code&gt;ss -tin state established '( dport = :443 )'\n# estab 0 0 10.0.0.5:443 198.51.100.20:51234\n#  cubic wscale:7,7 rto:204 rtt:28.1\/4.2 ato:40 mss:1448 pmtu:1500\n#  retrans:0\/14 rcv_mss:1400 unacked:2&lt;\/code&gt;<\/code><\/pre>\n<p><code>retrans:0\/14<\/code> on a fresh connection is the tell. Fourteen retransmits of the same lost segment means the segment is being dropped downstream and no ICMP &#8220;fragmentation needed&#8221; is coming back to tell the sender to shrink.<\/p>\n<h2>Test 1: Confirm PMTUD Fails From the Server Side<\/h2>\n<p>Send packets of increasing size with the Don&#8217;t Fragment bit set and see where they stop getting through. <code>ping<\/code> with <code>-M do<\/code> does exactly this:<\/p>\n<pre class=\"wp-block-code\"><code>&lt;code&gt;#!\/bin\/sh\n# sweep DF-set payloads from 1200 to 1472 bytes\nfor s in 1200 1300 1372 1400 1442 1452 1472; do\n  printf '%-6s ' \"$s\"\n  ping -c 2 -W 1 -M do -s $s 198.51.100.20 \\\n    | grep -q '1 received\\|2 received' &amp;&amp; echo OK || echo FAIL\ndone&lt;\/code&gt;<\/code><\/pre>\n<p>The largest successful payload plus 28 bytes of IPv4 and ICMP headers is the path MTU. If 1400 succeeds and 1442 fails, the path MTU is between 1428 and 1470 \u2014 very likely 1420, a common PPPoE or WireGuard value. Check what the kernel learned:<\/p>\n<pre class=\"wp-block-code\"><code>&lt;code&gt;ip route get 198.51.100.20\nip route show cache | grep -i mtu\ncat \/proc\/sys\/net\/ipv4\/route\/mtu_expires   # default 600s&lt;\/code&gt;<\/code><\/pre>\n<p>A cached <code>mtu<\/code> lower than the interface MTU means PMTUD is working for that destination \u2014 the problem is elsewhere. No cached MTU combined with the test failures above means ICMP is filtered.<\/p>\n<h2>Why ICMP Filtering Breaks Everything<\/h2>\n<p>Path MTU Discovery relies on routers sending ICMP type 3 code 4 (fragmentation needed) back to the sender. Firewalls treat ICMP as noise and drop it. The classic mistake is one line in an nftables or iptables ruleset: <code>ct state established,related accept<\/code> followed by <code>policy drop<\/code>, with no rule permitting ICMP.<\/p>\n<pre class=\"wp-block-code\"><code>&lt;code&gt;# nftables: permit the ICMP types PMTUD and error reporting depend on\nnft add rule inet filter input ip protocol icmp icmp type \\\n  { destination-unreachable, time-exceeded, parameter-problem } accept\nnft add rule inet filter input ip6 nexthdr icmpv6 \\\n  icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem } accept&lt;\/code&gt;<\/code><\/pre>\n<p>For IPv6, dropping <code>packet-too-big<\/code> is catastrophic because IPv6 routers never fragment \u2014 PMTUD is mandatory, and without it every connection above roughly 1280 bytes stalls. Rate-limit ICMP rather than dropping it:<\/p>\n<pre class=\"wp-block-code\"><code>&lt;code&gt;nft add rule inet filter input icmp type destination-unreachable \\\n  limit rate 20\/second burst 40 packets counter accept&lt;\/code&gt;<\/code><\/pre>\n<h2>Test 2: Trace the Black Hole<\/h2>\n<p>When the sweep fails, capture what actually happens during a failing transfer. Watch for duplicated sequence numbers with full-size payloads and no ICMP arriving:<\/p>\n<pre class=\"wp-block-code\"><code>&lt;code&gt;tcpdump -ni eth0 -s0 'host 198.51.100.20 and tcp port 443' -c 200 -w \/tmp\/pmtud.pcap\ntcpdump -nr \/tmp\/pmtud.pcap 'tcp[tcpflags] &amp; tcp-syn == 0' | head -20&lt;\/code&gt;<\/code><\/pre>\n<p>The signature is a repeated segment of length 1448 followed by a retransmission of the same sequence, with no smaller segment in between until the RTO ladder finishes. If a smaller segment does appear after an ICMP arrives, PMTUD is functioning and the stall has a different cause \u2014 an application-level timeout, or a load balancer with a mismatched idle timeout.<\/p>\n<p>For a documented example inside the kernel, enable TCP metrics export:<\/p>\n<pre class=\"wp-block-code\"><code>&lt;code&gt;ss -tin -o state established '( dport = :443 )' | grep -E 'retrans|mss|cwnd'\nnstat -az TcpExtTCPMTUPFail TcpExtTCPMTUPSuccess TcpRetransSegs&lt;\/code&gt;<\/code><\/pre>\n<p><code>TcpExtTCPMTUPFail<\/code> incrementing is direct evidence that MTU probing timed out on that route.<\/p>\n<h2>MSS Clamping: The Server-Side Fix<\/h2>\n<p>You cannot fix the client&#8217;s broken network, but you can stop the server from sending oversized segments. MSS clamping rewrites the MSS option during the handshake so both ends agree on a segment size that fits the smallest link:<\/p>\n<pre class=\"wp-block-code\"><code>&lt;code&gt;# clamp only on the interface facing clients\nnft add rule inet filter forward tcp flags syn tcp option maxseg size set rt mtu\n# or force a fixed value (e.g. 1360 for a 1400-byte path)\nnft add rule inet filter forward tcp flags syn tcp option maxseg size set 1360\n\niptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \\\n  -j TCPMSS --clamp-mss-to-pmtu&lt;\/code&gt;<\/code><\/pre>\n<p>With <code>rt mtu<\/code> the kernel uses the route MTU at handshake time, which is correct on a tunnel whose MTU is configured properly. The fixed-value form is for paths you know to be narrow regardless of routing \u2014 a WireGuard overlay at 1420 bytes wants MSS 1380 at most:<\/p>\n<table>\n<tr>\n<th>Link type<\/th>\n<th>Path MTU<\/th>\n<th>Recommended MSS<\/th>\n<\/tr>\n<tr>\n<td>Standard Ethernet<\/td>\n<td>1500<\/td>\n<td>1460<\/td>\n<\/tr>\n<tr>\n<td>WireGuard tunnel<\/td>\n<td>1420<\/td>\n<td>1380<\/td>\n<\/tr>\n<tr>\n<td>IPsec (ESP, AES-GCM)<\/td>\n<td>1400<\/td>\n<td>1360<\/td>\n<\/tr>\n<tr>\n<td>PPPoE<\/td>\n<td>1492<\/td>\n<td>1452<\/td>\n<\/tr>\n<tr>\n<td>IPv6 tunnel \/ 6in4<\/td>\n<td>1480<\/td>\n<td>1440<\/td>\n<\/tr>\n<\/table>\n<h2>Interface MTU and Kernel Behaviour<\/h2>\n<p>Lower the interface MTU when the whole path is narrower than the configured value \u2014 this is mandatory on tunnels:<\/p>\n<pre class=\"wp-block-code\"><code>&lt;code&gt;ip link set dev wg0 mtu 1420\nip link set dev eth0 mtu 1500\ncat \/proc\/sys\/net\/ipv4\/tcp_mtu_probing\ncat \/proc\/sys\/net\/ipv4\/tcp_base_mss&lt;\/code&gt;<\/code><\/pre>\n<p><code>tcp_mtu_probing<\/code> is the safety net for clients behind a black hole: with value <code>1<\/code> the kernel enables probing only after an initial connection stalls, and with <code>2<\/code> it probes always. Setting it to <code>2<\/code> on a public-facing server costs a few extra round trips per connection but makes large transfers survive broken paths:<\/p>\n<pre class=\"wp-block-code\"><code>&lt;code&gt;sysctl -w net.ipv4.tcp_mtu_probing=1\nsysctl -w net.ipv4.tcp_base_mss=1024\necho 'net.ipv4.tcp_mtu_probing=1' &gt;&gt; \/etc\/sysctl.d\/99-net.conf&lt;\/code&gt;<\/code><\/pre>\n<p>Do not enable probing globally as a substitute for fixing ICMP filtering. It masks one specific failure, adds latency, and leaves UDP-based protocols \u2014 QUIC included \u2014 unprotected.<\/p>\n<h2>Verification Checklist<\/h2>\n<ol>\n<li>DF sweep from server to client identifies the real path MTU per destination.<\/li>\n<li>ICMP types 3 and 11 (and ICMPv6 packet-too-big) permitted inbound, rate-limited.<\/li>\n<li>Interface MTU correct on every tunnel, matching the inner encapsulation overhead.<\/li>\n<li>MSS clamping applied to SYN packets on the client-facing path.<\/li>\n<li><code>ss -tin<\/code> shows no persistent unacked segments and a plausible <code>pmtu<\/code> value.<\/li>\n<li>Large transfer completes in a time consistent with bandwidth-delay product, not the 30-second RTO ladder.<\/li>\n<\/ol>\n<p>Run the sweep from at least two networks \u2014 a datacenter host and a consumer connection \u2014 because a black hole is often visible only from one side. Once the path MTU is known and clamping is in place, the 30-second stalls disappear without any change to TLS configuration: nothing was wrong with the certificate path in the first place. If large transfers are still slow after the fix, the limit has moved to socket buffers, and the <a href=\"https:\/\/virtualserversvps.com\/\">underlying instance&#8217;s bandwidth and buffer allocation<\/a> is the next thing to measure rather than another MTU experiment.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Most TLS failures that are not certificate errors are MTU problems wearing a disguise. The TCP handshake completes, the certificate verifies, the first small HTTP response arrives \u2014 and then&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":1,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1452","post","type-post","status-publish","format-standard","hentry","category-vps-guides-tutorials"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>MTU and PMTUD Black Holes: Diagnosing the Stalls That Look Like TLS Failures - Virtual Servers VPS Blog<\/title>\n<meta name=\"description\" content=\"Most TLS failures that are not certificate errors are MTU problems wearing a disguise. The TCP handshake completes, the certificate verifies, the first\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MTU and PMTUD Black Holes: Diagnosing the Stalls That Look Like TLS Failures\" \/>\n<meta property=\"og:description\" content=\"MTU and PMTUD Black Holes: Diagnosing the Stalls That Look Like TLS Failures\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual Servers VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-20T22:37:36+00:00\" \/>\n<meta name=\"author\" content=\"Virtual-Servers-Vps-Editor\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Virtual-Servers-Vps-Editor\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/\",\"name\":\"MTU and PMTUD Black Holes: Diagnosing the Stalls That Look Like TLS Failures - Virtual Servers VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\"},\"datePublished\":\"2026-10-20T22:37:36+00:00\",\"author\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\"},\"description\":\"Most TLS failures that are not certificate errors are MTU problems wearing a disguise. The TCP handshake completes, the certificate verifies, the first\",\"breadcrumb\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtualserversvps.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"MTU and PMTUD Black Holes: Diagnosing the Stalls That Look Like TLS Failures\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/\",\"name\":\"Virtual Servers VPS Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\",\"name\":\"Virtual-Servers-Vps-Editor\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"caption\":\"Virtual-Servers-Vps-Editor\"},\"sameAs\":[\"https:\/\/virtualserversvps.com\/blog\"],\"url\":\"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"MTU and PMTUD Black Holes: Diagnosing the Stalls That Look Like TLS Failures - Virtual Servers VPS Blog","description":"Most TLS failures that are not certificate errors are MTU problems wearing a disguise. The TCP handshake completes, the certificate verifies, the first","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/","og_locale":"en_US","og_type":"article","og_title":"MTU and PMTUD Black Holes: Diagnosing the Stalls That Look Like TLS Failures","og_description":"MTU and PMTUD Black Holes: Diagnosing the Stalls That Look Like TLS Failures","og_url":"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/","og_site_name":"Virtual Servers VPS Blog","article_published_time":"2026-10-20T22:37:36+00:00","author":"Virtual-Servers-Vps-Editor","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Virtual-Servers-Vps-Editor","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/","url":"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/","name":"MTU and PMTUD Black Holes: Diagnosing the Stalls That Look Like TLS Failures - Virtual Servers VPS Blog","isPartOf":{"@id":"https:\/\/virtualserversvps.com\/blog\/#website"},"datePublished":"2026-10-20T22:37:36+00:00","author":{"@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0"},"description":"Most TLS failures that are not certificate errors are MTU problems wearing a disguise. The TCP handshake completes, the certificate verifies, the first","breadcrumb":{"@id":"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/virtualserversvps.com\/blog\/mtu-pmtud-black-hole-troubleshooting\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtualserversvps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"MTU and PMTUD Black Holes: Diagnosing the Stalls That Look Like TLS Failures"}]},{"@type":"WebSite","@id":"https:\/\/virtualserversvps.com\/blog\/#website","url":"https:\/\/virtualserversvps.com\/blog\/","name":"Virtual Servers VPS Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0","name":"Virtual-Servers-Vps-Editor","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","caption":"Virtual-Servers-Vps-Editor"},"sameAs":["https:\/\/virtualserversvps.com\/blog"],"url":"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/"}]}},"_links":{"self":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1452","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/comments?post=1452"}],"version-history":[{"count":1,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1452\/revisions"}],"predecessor-version":[{"id":1453,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1452\/revisions\/1453"}],"wp:attachment":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/media?parent=1452"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/categories?post=1452"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/tags?post=1452"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}