<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: BookMyHost</title>
    <description>The latest articles on DEV Community by BookMyHost (@bookmyhost).</description>
    <link>https://dev.to/bookmyhost</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4181836%2Fcf5af523-0121-4973-b3d5-0a8d5f7371fb.png</url>
      <title>DEV Community: BookMyHost</title>
      <link>https://dev.to/bookmyhost</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bookmyhost"/>
    <language>en</language>
    <item>
      <title>Works on desktop, fails on phones: the post-quantum TLS bug hiding in your network card</title>
      <dc:creator>BookMyHost</dc:creator>
      <pubDate>Wed, 14 Oct 2026 21:17:14 +0000</pubDate>
      <link>https://dev.to/bookmyhost/works-on-desktop-fails-on-phones-the-post-quantum-tls-bug-hiding-in-your-network-card-4pln</link>
      <guid>https://dev.to/bookmyhost/works-on-desktop-fails-on-phones-the-post-quantum-tls-bug-hiding-in-your-network-card-4pln</guid>
      <description>&lt;p&gt;Modern browsers now send a larger TLS hello. On some Windows servers, a receive-offload bug in the network card silently breaks about half of those connections. Here is how to spot it, why it happens, and the two ways to fix it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The complaint
&lt;/h2&gt;

&lt;p&gt;"The site opens fine on my laptop, but my phone says &lt;em&gt;This site can't be reached&lt;/em&gt;." The server looks healthy: no errors in the web server logs, CPU normal, the firewall shows nothing blocked. Reload a few times and the page sometimes loads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Symptoms
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Browsers show &lt;code&gt;ERR_CONNECTION_RESET&lt;/code&gt;, &lt;code&gt;ERR_CONNECTION_TIMED_OUT&lt;/code&gt;, &lt;code&gt;ERR_CONNECTION_ABORTED&lt;/code&gt; or "Check your internet connection", &lt;strong&gt;intermittently&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Phones notice it first; desktops seem fine.&lt;/li&gt;
&lt;li&gt;The web server logs nothing for the failed attempts, because the request never gets that far.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;curl&lt;/code&gt; or a TLS 1.2 test from your own network always works.&lt;/li&gt;
&lt;li&gt;CDN/DDoS dashboards show no drops.&lt;/li&gt;
&lt;li&gt;The server runs &lt;strong&gt;Windows Server&lt;/strong&gt; with &lt;strong&gt;Receive Segment Coalescing (RSC)&lt;/strong&gt; enabled on its network card.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is actually going on
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The hello got bigger.&lt;/strong&gt; Chrome, Edge and Firefox now add a post-quantum key exchange (&lt;code&gt;X25519MLKEM768&lt;/code&gt;) to every TLS 1.3 handshake. That adds over a kilobyte to the ClientHello. At about 1.8 KB it no longer fits in one TCP packet, so it arrives as &lt;strong&gt;two segments&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The card merges them, and gets one field wrong.&lt;/strong&gt; RSC lets the network card combine back-to-back segments before Windows sees them. In the environment we observed (NVIDIA/Mellanox ConnectX-4 Lx, WinOF-2 driver 2.42), the merged segment arrived with the top bit of its &lt;strong&gt;TCP timestamp&lt;/strong&gt; cleared.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows then throws the rest away.&lt;/strong&gt; TCP's PAWS check discards segments whose timestamp looks older than the last one accepted. With the top bit flipped, the second half of the ClientHello looks "from the past" and is dropped, on every retransmit. The handshake never completes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why only half the time.&lt;/strong&gt; Clients start TCP timestamps at a random value, so the top bit is set on about &lt;strong&gt;50%&lt;/strong&gt; of connections. Those are the ones that fail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why "only phones".&lt;/strong&gt; It isn't really a phone bug. Desktops tend to reuse an existing open connection, while phones open fresh ones constantly as radios sleep and networks switch. Older clients send a hello small enough to fit in one packet.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to confirm it in two minutes
&lt;/h2&gt;

&lt;p&gt;From any Linux machine outside your network (OpenSSL 3.5 or newer), compare a large and a small key share:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;10&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; | &lt;span class="nb"&gt;timeout &lt;/span&gt;5 openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; YOUR_IP:443 &lt;span class="nt"&gt;-tls1_3&lt;/span&gt; &lt;span class="nt"&gt;-groups&lt;/span&gt; X25519MLKEM768 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN CERT"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done
for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;10&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; | &lt;span class="nb"&gt;timeout &lt;/span&gt;5 openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; YOUR_IP:443 &lt;span class="nt"&gt;-tls1_3&lt;/span&gt; &lt;span class="nt"&gt;-groups&lt;/span&gt; x25519 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN CERT"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the first loop fails several times and the second never fails, this is your bug. A packet capture on the server shows the second segment dropped, and the first segment's timestamp exactly 2^31 away from the client's.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix 1: on the server
&lt;/h2&gt;

&lt;p&gt;Disable RSC in Windows. It takes effect immediately, without resetting the adapter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;netsh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tcp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;global&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rsc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;disabled&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also check your NIC vendor for a newer driver or firmware. In our tests, phone-style handshakes went from failing about half the time to &lt;strong&gt;20 out of 20&lt;/strong&gt; succeeding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix 2: at the network edge (what we did)
&lt;/h2&gt;

&lt;p&gt;One server is easy. Finding every affected server in a datacentre is not. So our edge routers now remove the TCP timestamp option from incoming &lt;strong&gt;SYN&lt;/strong&gt; packets. A connection that starts without timestamps never uses them, so there is nothing for the card to corrupt and nothing for PAWS to drop. On a Linux/nftables router it is one rule in a forward chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight bpf"&gt;&lt;code&gt;tcp flags syn / syn,ack,rst tcp option timestamp exists reset tcp option timestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two details matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Strip SYNs only, never SYN-ACKs.&lt;/strong&gt; If traffic is asymmetric and only the reply were stripped, the two ends would disagree about timestamps, which is worse than the original bug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The cost is small.&lt;/strong&gt; You lose the timestamp option's finer RTT measurement and its protection for very fast single flows. On a busy edge router the CPU cost was too small to measure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;When "some users can't connect" and every log is clean, test the way your users connect: modern browser, fresh connection, post-quantum key share. More of the internet now sends handshakes that need two packets, and old offload bugs are coming back into view.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bookmyhost.com/guides/site-works-on-desktop-fails-on-phone-post-quantum-tls" rel="noopener noreferrer"&gt;BookMyHost blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>security</category>
      <category>devops</category>
      <category>windows</category>
    </item>
  </channel>
</rss>
