AlgoMaster Logo

TCP Header Anatomy

Medium Priority27 min readUpdated August 14, 2026
Listen to this chapter
Unlock Audio

Every TCP segment begins with a header that tells the receiving TCP implementation where the bytes belong, which connection they belong to, what control events they represent, how much data the receiver can currently accept, and whether the segment was damaged.

The smallest TCP header is 20 bytes. Options can extend it to 60 bytes, after which the segment may carry application data.

Reading these fields turns a packet capture from a list of opaque packets into a precise record of connection behavior. A single header can reveal:

  • The two transport ports
  • The stream position of its payload
  • The next byte expected from the peer
  • Connection-control signals such as SYN, FIN, or RST
  • The advertised receive window
  • Negotiated capabilities and measurement data
  • Whether the checksum passed validation

This chapter develops a byte-level model of that header and shows how to decode one manually.

TCP Segment Layout

A TCP segment consists of a TCP header followed by zero or more payload bytes. The complete segment becomes the payload of an IP packet.

The fixed 20-byte portion contains every field except options, padding, and data:

Byte OffsetFieldSize
0–1Source port16 bits
2–3Destination port16 bits
4–7Sequence number32 bits
8–11Acknowledgment number32 bits
12Data offset, reserved bits, and AE8 bits total
13CWR through FIN control flags8 bits
14–15Window16 bits
16–17Checksum16 bits
18–19Urgent pointer16 bits
20 onwardOptions, padding, then dataVariable

Multi-byte fields use network byte order, which places the most significant byte first. The bytes 01 bb therefore represent hexadecimal 0x01bb, or decimal port 443.

Loading simulation...

Source and Destination Ports

The first four bytes contain two 16-bit port numbers.

The source port identifies the sending transport endpoint. The destination port identifies the receiving transport endpoint. At a server, the destination is commonly a well-known or configured service port, while a client commonly uses a temporary local port.

For a client request:

The reply reverses those values:

A port number alone does not identify a TCP connection. TCP combines both ports with the source and destination IP addresses:

The IP addresses are not repeated in the TCP header; they remain in the surrounding IP header.

Port values range from 0 through 65535, although port 0 is reserved rather than used as an ordinary service endpoint. IANA divides the remaining space into system, user, and dynamic/private ranges. Operating systems choose their actual ephemeral-port ranges through local policy, so an observed client port should not be classified by assumption alone.

Sequence Number

The 32-bit sequence number identifies a position in the sender's byte stream.

For an ordinary data segment, it is the number of the first payload byte:

Sequence numbers count bytes, not packets. Two segments carrying different payload lengths advance the stream by different amounts.

The arithmetic wraps modulo 2^32. After 4,294,967,295, the next sequence value is 0. TCP compares wrapped values within a valid receive window rather than treating them as ordinary unbounded integers.

SYN changes the interpretation slightly. In a SYN segment, the field contains the Initial Sequence Number, and the first data byte begins at ISN plus one. SYN and FIN each consume one sequence position even when they carry no payload. A pure ACK consumes none.

Packet analyzers often display relative sequence values such as 0, 1, and 501 instead of the 32-bit values transmitted on the wire. Relative values make a flow easier to follow, but raw values are necessary when manually matching header bytes.

Acknowledgment Number

The 32-bit acknowledgment number identifies the next sequence number the sender of this segment expects to receive from the other endpoint.

Suppose an endpoint has received all peer bytes through 10499:

This means "send me byte 10500 next." It cumulatively confirms that the continuous stream prefix before 10500 arrived.

The field is meaningful when the ACK flag is set. Once a connection is established, ordinary TCP segments set ACK, including segments that also carry application data.

Sequence and acknowledgment fields describe opposite directions:

Do not add a segment's acknowledgment number to its sequence number. They belong to different byte streams.

Data Offset and Header Length

TCP has no fixed header-length byte. Instead, the four-bit Data Offset field reports the header size in units of 32-bit words.

The smallest valid value is 5:

A header with 12 bytes of options uses:

Because four bits can hold at most 15, the largest ordinary TCP header is:

That leaves at most 40 bytes for options and padding.

The field is called Data Offset because it identifies the offset, measured from the start of the TCP header, at which payload data begins. A receiver must use it rather than assuming that byte 20 begins the payload.

A value below 5, a header length beyond the available IP payload, or options that overrun the declared header boundary indicates a malformed or truncated segment.

Reserved Bits and the AE Flag

The lower part of byte 12 follows Data Offset.

In the current TCP registry, three bits remain reserved for future use. Senders transmit unassigned reserved bits as zero, while receivers ignore assignments they do not implement.

The fourth position is now assigned as AE, for Accurate ECN. When both endpoints support Accurate Explicit Congestion Notification, AE works with CWR and ECE as a compact feedback field that reports congestion markings more precisely.

This assignment explains why header diagrams can differ:

  • The base TCP specification published in 2022 shows four reserved bits.
  • Some older diagrams label the last of those bits NS for the now-historic ECN Nonce.
  • The current IANA registry assigns that position to AE.

For a connection that did not negotiate Accurate ECN, seeing AE set requires careful interpretation rather than assuming that it is an ordinary application flag.

The Eight Classic Control Flags

Byte 13 contains eight one-bit control flags:

Several flags can be set in one segment. A SYN-ACK uses SYN and ACK; an ordinary data segment commonly uses ACK and may use PSH; a graceful close segment commonly uses FIN and ACK.

SYN

SYN, or synchronize, establishes sequence-number state. Its sequence field contains the sender's initial sequence number. SYN consumes one sequence position.

ACK

ACK says that the acknowledgment-number field is significant. It does not mean that the segment contains no data. Most packets in an established connection carry ACK alongside data or another control flag.

FIN

FIN says that no bytes follow after this point in the sender's stream. FIN participates in graceful directional shutdown and consumes one sequence position.

RST

RST resets or aborts a connection. It reports that the expected connection state does not exist or is being abandoned. A reset is different from an orderly EOF.

PSH

PSH, or push, indicates that the sender intends the associated data to be transmitted and delivered promptly rather than held for further aggregation.

PSH is not a message boundary. TCP remains a byte stream, and a receiver must not use PSH to infer where an HTTP request, database record, or application write ends. Operating systems may also provide limited or no direct application control over the flag.

URG

URG says that the urgent-pointer field is significant. TCP urgent data was designed to mark a position requiring prompt attention within the stream.

URG does not create a separate reliable side channel. Application APIs and historical implementations have handled urgent data inconsistently, so modern application protocols rarely depend on it.

ECE and CWR

ECE, or ECN-Echo, and CWR, or Congestion Window Reduced, support Explicit Congestion Notification.

With classic ECN, a receiver uses ECE to report that the network marked a packet as experiencing congestion. The sender uses CWR to indicate that it received and reacted to that signal. During connection setup, the same flags also participate in negotiating ECN support.

When Accurate ECN is negotiated, AE, CWR, and ECE are interpreted together to carry more detailed congestion feedback. The header flags carry the signal; the algorithms that change the sending rate are separate behavior.

Window

The 16-bit Window field advertises how many bytes the sender of this segment is currently willing to receive, beginning at the byte named by its acknowledgment number.

For example:

This is a receive window advertisement. It describes space at the endpoint sending the header, not permission for that endpoint's own outbound stream.

A raw 16-bit window can represent values through 65535. The Window Scale option can expand the effective value after it is negotiated during connection setup:

The window values in SYN segments are not scaled. A packet analyzer needs the handshake's Window Scale options to calculate later effective windows correctly.

A zero window means the receiver is temporarily advertising no additional buffer space. It does not mean the connection is closed. How TCP pauses and later resumes transmission belongs to the flow-control behavior built on top of this field.

Checksum

The 16-bit checksum detects corruption affecting:

  • The TCP header
  • TCP options and padding
  • The TCP payload
  • Selected information from the surrounding IP header

TCP uses a one's-complement checksum. The sender conceptually places zero in the checksum field, sums the protected data as 16-bit words using one's-complement arithmetic, and stores the complement of the result.

If the protected byte count is odd, the calculation uses one zero byte for alignment. That byte participates only in the calculation and is not transmitted.

The TCP checksum is mandatory with both IPv4 and IPv6.

The Pseudo-Header

The checksum includes a conceptual pseudo-header derived from IP:

The pseudo-header is not transmitted as part of TCP. Its fields are included in the calculation so that corruption or misdelivery involving IP endpoints, transport protocol, or TCP length can invalidate the checksum.

For IPv4, the pseudo-header contains the source and destination addresses, a zero byte, the TCP protocol number, and TCP length. IPv6 uses its addresses, upper-layer packet length, zero padding, and the applicable next-header value.

The checksum detects accidental errors; it does not provide cryptographic integrity or authenticate the sender. An attacker who can modify a segment can calculate a new checksum.

Checksum Offloading

A host capture can mark an outgoing checksum as incorrect even when the packet transmitted on the wire is valid. With checksum offloading, the operating system hands a partially prepared packet to the network interface, and the hardware fills in the checksum after the host capture point.

Before diagnosing a bad checksum, determine whether the packet was captured before or after offload processing. A capture at the receiving endpoint or an external observation point can distinguish a display artifact from actual corruption.

Urgent Pointer

The 16-bit urgent pointer is interpreted only when URG is set.

It is a positive offset from the segment's sequence number and points to the sequence number of the byte immediately following the urgent data:

Without URG, the field has no protocol meaning even if its bits are nonzero.

Urgent data has rare, legacy uses and inconsistent application interfaces. For packet analysis, the essential rule is to evaluate URG and the pointer together. A nonzero pointer by itself does not mark urgent data.

TCP Options and Padding

Options extend TCP without changing the fixed 20-byte header. Each option begins with a one-byte Kind value.

Kinds 0 and 1 are single-byte options. Every other option begins:

The length includes the Kind and Length bytes.

Common options include:

KindOptionLengthTypical Purpose
0End of Option List1 byteMarks the end of meaningful options
1No-Operation1 byteAligns later options
2Maximum Segment Size4 bytesAdvertises the largest TCP payload the sender is prepared to receive
3Window Scale3 bytesAdvertises a receive-window scaling shift
4SACK Permitted2 bytesAnnounces support for selective acknowledgments
5SACKVariableReports received byte ranges beyond a gap
8Timestamps10 bytesCarries a timestamp value and echoed timestamp

MSS, Window Scale, and SACK Permitted are exchanged in SYN segments because the endpoints need those capabilities at connection setup. A SACK option appears later only when it has useful received ranges to report. Timestamps, once negotiated, commonly appear throughout the connection.

Options do not need to begin on a 32-bit boundary. No-Operation bytes are nevertheless commonly inserted for alignment. Because Data Offset expresses whole 32-bit words, the complete header must end on a four-byte boundary.

After an End of Option List marker, any remaining bytes through the declared header end are zero padding. Unknown well-formed options are ignored by implementations that do not support them.

The 40-byte maximum creates option-space pressure. A SYN may want MSS, Window Scale, SACK Permitted, timestamps, and other extensions, but all encoded options and padding must fit before the 60-byte header boundary.

TCP Has No Payload-Length Field

TCP does not carry a field saying how many application bytes are in the segment. The receiver derives the value from the enclosing IP packet and Data Offset.

For a basic IPv4 packet:

Suppose:

With IPv6, the calculation must also account for any extension headers between the IPv6 base header and TCP.

A packet analyzer's reported TCP segment length is usually this derived payload size. It is not copied from a TCP header field.

This also explains common maximum payload sizes on a 1500-byte path:

Options consume space that could otherwise carry payload within the same IP packet size.

Manually Decoding a TCP Header

Consider this illustrative 32-byte TCP header:

The checksum value is illustrative; validating it would also require the IP addresses, TCP length, and payload.

Ports

Sequence and Acknowledgment

Data Offset, Reserved Bits, and AE

Flags

This segment has ACK and PSH set. It is not a SYN, FIN, or RST.

Window, Checksum, and Urgent Pointer

The effective window cannot be determined from this isolated header if window scaling was negotiated. The handshake is needed to find the scale factor.

Options

The base header ends after 20 bytes. Data Offset says the header is 32 bytes, so 12 bytes remain as options:

The application payload, if any, begins immediately after the final byte 32.

Reading the Header in a Capture

Capture the TCP header and raw bytes with:

Replace en0 with the relevant interface.

  • -nn keeps addresses and ports numeric.
  • -vvv prints more decoded header information.
  • -S shows absolute sequence numbers.
  • -X displays hexadecimal bytes and ASCII.

In Wireshark, expand the Transmission Control Protocol section and compare the decoded fields with the packet bytes pane. Selecting a field highlights its exact bytes, which is useful for confirming Data Offset, flags, options, and network byte order.

Use the surrounding IP information when interpreting TCP:

  • IP addresses complete the connection identity.
  • IP length determines TCP payload length.
  • IP ECN bits provide context for TCP ECN feedback.
  • The pseudo-header is necessary for checksum validation.

TLS encrypts application content carried inside TCP, but ordinary TLS does not hide the TCP ports, sequence numbers, acknowledgments, flags, window, or options. Those fields remain available for transport-level troubleshooting.

Offloads Can Change the Capture View

Modern hosts reduce CPU work by moving TCP operations into network hardware or combining work in the kernel.

TCP Segmentation Offload, often grouped with generic segmentation offload, lets the host hand a large buffer to the interface. The interface divides it into wire-sized segments later. A capture taken before that division can display a TCP payload far larger than the path would carry in one packet.

Generic Receive Offload or Large Receive Offload can combine several received segments before higher layers process them. A host capture can then show a large synthetic unit rather than every original wire segment.

Checksum offload can leave the pre-hardware checksum incomplete, as described earlier.

These features do not change the TCP format transmitted between endpoints. They change where segmentation, aggregation, and checksum work occurs relative to the capture point.

When exact on-wire headers matter, capture after offload processing, disable the relevant offload temporarily in a controlled environment, or use an external observation point.

Diagnosing Header-Level Problems

Data begins at the wrong byte: Decode Data Offset first. TCP options can move the payload beyond byte 20.

A sequence jump looks too large: Check the segment's payload length, SYN or FIN consumption, relative-number display, capture loss, and host offload behavior.

The acknowledgment seems unrelated to the sequence number: Remember that acknowledgment refers to the peer's stream, not the current segment's stream.

The advertised window appears unexpectedly small: Distinguish the raw 16-bit field from the scaled effective value and recover the negotiated scale from the handshake.

The window is zero: The receiver is temporarily advertising no additional capacity. It is not a FIN or RST.

The checksum appears invalid only on outgoing packets: Suspect checksum offloading before assuming wire corruption.

The capture shows a payload larger than the MTU: Determine whether segmentation or receive offload changed the host-side view.

Expected TCP options are absent: Compare both SYNs, confirm the header length, and consider whether the endpoint or a middlebox removed or rejected an option.

PSH appears at unexpected boundaries: Do not use PSH as application framing. Reconstruct the byte stream using application protocol rules.

Common Misunderstandings

The minimum TCP header is 20 bytes, not every TCP header. Data Offset determines the actual size through a maximum of 60 bytes.

Sequence numbers count bytes, not segments. Payload length, SYN, and FIN determine how the value advances.

Acknowledgment and sequence numbers describe opposite directions. They should not be combined as though they belonged to one counter.

ACK is a validity flag, not a packet type. A segment can carry ACK together with data, SYN, FIN, PSH, or other flags.

PSH does not preserve application writes. It is not a record or message delimiter.

A zero window does not close the connection. It advertises temporary receive-buffer limits.

TCP has no payload-length field. The length is derived from IP length and TCP Data Offset.

The pseudo-header is checked but not transmitted inside TCP. It contributes selected IP information to the checksum calculation.

A valid checksum is not authentication. It detects accidental errors rather than malicious modification.

A bad host-capture checksum may be an offload artifact. The capture point determines whether hardware has finished the header.

Older flag diagrams can be outdated. The current registry assigns AE where older documents showed a reserved or historic NS bit.

Summary

The TCP header places a segment within a bidirectional byte stream. Ports identify transport endpoints, with IP addresses completing the connection identity. The sequence number locates the first payload byte; the acknowledgment number gives the next byte expected from the opposite direction.

Data Offset encodes a 20-to-60-byte header in 32-bit words. The current layout includes three reserved bits, AE, and eight classic flags from CWR through FIN. SYN and FIN consume sequence space, a pure ACK does not, and PSH requests prompt handling without marking a message boundary. The Window field advertises receive capacity, possibly through a negotiated scale factor.

The mandatory checksum covers the header, options, payload, and IP pseudo-header. URG gives meaning to the urgent pointer. Options occupy at most 40 bytes, padding aligns the header to four bytes, and payload length is derived from the IP length and Data Offset. Host offloads can make captures differ from the wire.

Read ports and stream positions first, then the header boundary, flags, window, checksum context, options, and payload.

Quiz

TCP Header Anatomy Quiz

5 quizzes