In TCP, what does the MSS option announce, how is its value derived, and what is assumed when a SYN omits it?
answer
- largest segment I can receive
- payload only, headers excluded
- MTU minus fixed IP and TCP
- not agreed, announced per side
- the 576 and 1280 minimums
basics
~20 sThe MSS option announces the largest TCP payload the sender of the SYN can receive, normally its MTU minus fixed IP and TCP headers (1460 on a 1500-byte IPv4 link). Without it, the peer assumes 536 for IPv4 or 1220 for IPv6.
solid answer
~50 s`MSS` (option kind 2, 4 bytes) may only be sent in a segment with SYN set, and it tells the peer the largest segment, TCP payload only, that its sender can receive. It is an announcement, not a negotiation: each side sends its own value, so the two directions can use different sizes. RFC 9293 says the value should be the effective MTU minus the fixed IP and TCP headers, so a 1500-byte MTU gives 1460 over IPv4 and 1440 over IPv6; RFC 6691 explains why options are not subtracted when advertising it. The sender then fits each segment within the peer's MSS and its own IP limit, minus whatever option bytes that segment carries. If no MSS arrives, RFC 9293 requires assuming 536 for IPv4 (576 - 40) or 1220 for IPv6 (1280 - 60).
go deeper
Know that MSS is the largest TCP payload and MTU the largest IP packet, and that 1460 is 1500 minus two 20-byte headers.
Explain that each side announces what it can receive in its SYN, how options reduce the data per segment, and the 536 and 1220 defaults.
Use per-direction MSS to explain asymmetric behaviour in a capture, and know why the announced value cannot reflect a narrower link in the middle of the path.
Discuss why a receive-side announcement fixed at connection setup is a weak signal for path size, and what packetization-layer probing adds for long-lived flows.
## MTU and MSS are different limits Two numbers get confused constantly: | Term | Layer | What it limits | Includes headers? | |---|---|---|---| | **MTU** (maximum transmission unit) | Link and IP | Largest IP packet a link carries in one piece | Yes: the IP header, the TCP header and the data | | **MSS** (maximum segment size) | TCP | Largest TCP payload one endpoint is willing to receive | No: data bytes only | On an Ethernet link the MTU is 1500 bytes. An IPv4 header without options is 20 bytes and a TCP header without options is 20 bytes, so the most TCP data that fits in one packet is 1460. That is why 1460 is the MSS most people have seen. ## What the option is and when it is sent The MSS option is kind 2, length 4, carrying a 16-bit value. RFC 9293 makes three rules: - It "may be sent in the initial connection request (i.e., in segments with the SYN control bit set) and **MUST NOT** be sent in other segments". There is no way to change it later in the connection. - Every TCP **MUST** implement sending and receiving it. - A TCP **SHOULD** send it in every SYN whenever its receive MSS differs from the default, and **MAY** always send it. The value "communicates the maximum receive segment size at the TCP endpoint that sends this segment". It is about what the announcer can **receive**, not what it will send. ## Deriving the value RFC 9293 says the MSS to advertise "should be equal to the effective MTU minus the fixed IP and TCP headers": 1. Start from the MTU of the interface the connection uses. 2. Subtract the fixed IP header: 20 bytes for IPv4, 40 for IPv6. 3. Subtract the fixed TCP header: 20 bytes. 4. Advertise the result. | Interface MTU | IP version | MSS to advertise | |---|---|---| | 1500 | IPv4 | 1460 | | 1500 | IPv6 | 1440 | | 9000 | IPv4 | 8960 | Options are deliberately **not** subtracted. RFC 6691 explains the historical confusion: the advertiser cannot know which options later segments will carry, so the **sender** must shrink each segment's data by the IP and TCP option bytes it actually includes. ## What the sender actually uses RFC 9293 defines the **effective send MSS**: `Eff.snd.MSS = min(SendMSS + 20, MMS_S) - TCPhdrsize - IPoptionsize` Here `SendMSS` is the peer's announced value (or the default), `MMS_S` is the largest transport message this host's IP layer lets it send, and `TCPhdrsize` is 20 plus any TCP options. So with a peer MSS of 1460 and the 12 bytes that timestamps take with padding, each full segment carries 1448 bytes of data. ## Not a negotiation Because each side announces what it can receive, the result is **per direction**: - The client's announced MSS caps what the server sends to the client. - The server's announced MSS caps what the client sends to the server. - Neither side adopts the smaller of the two for both directions. ## The defaults when the option is missing RFC 9293 says that if no MSS option is received at connection setup, a TCP **MUST** assume **536 for IPv4** (576 - 40) or **1220 for IPv6** (1280 - 60). The arithmetic comes from the minimum sizes each IP version guarantees: RFC 1122 notes that no IPv4 host is required to accept a datagram larger than 576 bytes, and RFC 8200 requires every IPv6 link to carry 1280-byte packets. Subtract 20 bytes of IPv4 header or 40 of IPv6, and 20 of TCP. ## What MSS does not do - It does **not** discover the path. It reflects the announcer's own link, not a smaller link in the middle. - It does **not** stop fragmentation or loss on a narrower hop; Path MTU Discovery and MSS clamping by a router on that hop deal with that. - Advertising a needlessly small value, such as 536 to every non-local destination, limits what Path MTU Discovery can find, as RFC 9293 notes.
- A client's SYN announces MSS 1360 and the server's SYN-ACK announces MSS 1460. What segment sizes flow in each direction?Server-to-client segments carry at most 1360 bytes of data, because the client's value limits what the client receives. Client-to-server segments may carry up to 1460, limited also by the client's own interface and by any option bytes in each segment. The two directions are independent; nobody settles on one common value.
- Why does the IPv4 default MSS work out to exactly 536 bytes?RFC 1122 notes that no IPv4 host is required to accept a datagram larger than 576 bytes without prior arrangement. Taking away a 20-byte IPv4 header and a 20-byte TCP header leaves 536, which RFC 9293 writes as 576 - 40. The IPv6 default of 1220 comes the same way from the 1280-byte minimum link MTU minus 40 and 20.
Each end pins a notice on its own letterbox: parcels up to this size fit. The two notices can differ, and each one only limits what is posted into that box, never what its owner sends out.
saying these in an interview costs you the question
- MSS includes the IP and TCP headers, so it equals the MTU
- Both sides agree on one shared MSS during the handshake
- A TCP can raise or lower its MSS mid-connection by resending the option
- Without an MSS option, the peer assumes 1460 bytes
- The advertised MSS already subtracts every TCP option the connection will use