The IPv6 header is 40 bytes fixed (40 octets), with eight fields. That is the base header size, even when extension headers follow it. Payload Length counts everything after those 40 bytes, including extension headers. In the lab Echo Request below, it is 64 bytes, so the IPv6 packet is 104 bytes total.
| Base-header field | Captured Echo Request value |
|---|---|
| Version | 6 |
| Traffic Class | 0xb8 (DSCP EF, ECN Not-ECT) |
| Flow Label | 0x03039 (12345) |
| Payload Length | 64 bytes |
| Next Header | ICMPv6 (58) |
| Hop Limit | 37 |
| Source Address | 2001:db8:106::1 |
| Destination Address | 2001:db8:106::2 |
This article walks through the IPv6 header byte by byte, explains each field, covers extension headers (the IPv6 way of adding optional features), and shows how the header looks in Wireshark. If you are studying for CCNP-level exams or trying to read an IPv6 packet capture, this is the byte reference.
The IPv6 Header Layout
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| Traffic Class | Flow Label |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload Length | Next Header | Hop Limit |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Source Address +
| (128 bits / 16 bytes) |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Destination Address +
| (128 bits / 16 bytes) |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+40 bytes total: 8 bytes of header fields plus 16 bytes source address plus 16 bytes destination address.

Field by Field
Version
4 bits. Value is always 6 for IPv6 packets. The first hex digit of the header is always 6 (followed by the upper nibble of the Traffic Class).
Traffic Class
8 bits. Functions identically to the IPv4 ToS / DSCP byte. Top 6 bits are DSCP (QoS marking, see DSCP article); bottom 2 bits are ECN (Explicit Congestion Notification).
QoS configurations on Cisco apply identically to IPv4 and IPv6 - a class-map matching DSCP EF works on both because the byte position differs but the semantics are the same.
Flow Label
20 bits. Identifies a "flow" of packets that should follow the same path through the network. The intent: routers can use the flow label as a hash input for ECMP without parsing into Layer 4 headers. Identical Flow Label = same flow, deterministic path.
In practice, Flow Label adoption has been mixed. Some implementations set it; many leave it 0. Routers may or may not honor it for ECMP. RFC 6437 sets the modern usage rules but real-world behavior varies. Treat it as "useful when the surrounding stack honors it; ignored otherwise."
Payload Length
16 bits. Length in bytes of everything after the 40-byte header. Maximum value 65,535 = 64 KB minus 1; for jumbograms larger than 64 KB, the Hop-by-Hop extension header carries an extended length field.
Note this is "payload" length, not "total" length (as in IPv4). The 40-byte header itself is excluded. So an IPv6 packet on the wire is always 40 + Payload Length bytes total.
Next Header
8 bits. Identifies the type of the next thing in the packet. This is roughly equivalent to IPv4's Protocol field but with two important differences:
- It can point to a Layer 4 protocol directly (TCP=6, UDP=17, ICMPv6=58)
- It can point to an Extension Header that itself contains another Next Header field
This creates a chained-header model. Common Next Header values:
Hop Limit
8 bits. Decremented at each router that forwards the packet. Packet is dropped when Hop Limit reaches 0; ICMPv6 Time Exceeded message is sent back to the source. Equivalent to IPv4 TTL.
Default starting values vary by stack: 64 on most Linux distributions, 128 on Windows. 255 is not a general host default; it is the value NDP messages are required to carry. Whatever the starting value, a packet dropped on Hop Limit has traversed that many routers, which is what makes traceroute work.
The Hop Limit also serves a security role: NDP messages (RS, RA, NS, NA, Redirect) must have Hop Limit 255 when received, otherwise they are dropped. This prevents off-link attackers from injecting NDP messages because their packets would have decremented Hop Limit while transiting routers.
Source and Destination Addresses
128 bits each. The IPv6 addresses (see IPv6 Address Format for the format details).
16 bytes each = 32 bytes of address space, which is most of the 40-byte header. The minimalism of the rest of the header is partly because the addresses themselves consume so much.
Extension Headers
IPv6 moves features that were "options" in IPv4 into separate extension headers chained between the base header and the payload. Each extension header has its own Next Header field pointing to whatever comes next.
The chain terminates when a Next Header value points to a real Layer 4 protocol (TCP, UDP, ICMPv6) or to "No Next Header" (59).
Most ordinary IPv6 packets have no extension headers - the base header points directly to TCP/UDP/ICMPv6. Extension headers are common for fragments, IPsec, and segment routing.
In the baseline capture below, Next Header is 58: ICMPv6 follows the base header directly. The large ping changes that field to 44, pointing to a Fragment Header whose own Next Header is 58. The base header stays 40 bytes in both captures; the extra 8-byte Fragment Header counts toward Payload Length.
Comparison to the IPv4 Header
The biggest change is removing the header checksum. IPv4 routers had to recalculate the checksum each time they decremented TTL - an expensive operation that ASIC designers worked hard to optimize. IPv6 routers do not. The Layer 2 (Ethernet) FCS and Layer 4 (TCP/UDP) checksums together catch errors; the IP-layer checksum was redundant.
In a Packet Capture
Decoded from a real lab capture
Topology: two Alpine 3.24.2 hosts, 2001:db8:106::1 ↔ 2001:db8:106::2, directly connected on eth1 with an MTU of 1500. There is no router between them. Both captures were taken on the target's eth1 interface.
Frame 1 of baseline.pcap is a real ICMPv6 Echo Request carrying 56 ping data bytes. This is an excerpt of the full tshark -V decode; standalone ... lines mark omitted lines.
Internet Protocol Version 6, Src: 2001:db8:106::1, Dst: 2001:db8:106::2
0110 .... = Version: 6
.... 1011 1000 .... .... .... .... .... = Traffic Class: 0xb8 (DSCP: EF, ECN: Not-ECT)
.... 1011 10.. .... .... .... .... .... = Differentiated Services Codepoint: Expedited Forwarding (46)
.... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0)
.... 0000 0011 0000 0011 1001 = Flow Label: 0x03039
Payload Length: 64
Next Header: ICMPv6 (58)
Hop Limit: 37
Source Address: 2001:db8:106::1
...
Destination Address: 2001:db8:106::2
...
Internet Control Message Protocol v6
Type: Echo (ping) request (128)
Code: 0
Checksum: 0x8815 [correct]
[Checksum Status: Good]
The values were deliberately selected to make the fields easy to spot. Here is how each one maps to the header layout:
| Field | Width | Reading this capture |
|---|---|---|
| Version | 4 bits | 6, the first nibble of the IPv6 header. |
| Traffic Class | 8 bits | 0xb8 (184). The sender selected it with -Q 0xb8; TShark splits it into DSCP EF (46) and ECN Not-ECT (0). This shows the marking, not QoS scheduling. |
| Flow Label | 20 bits | 0x03039 (12345), explicitly selected with -F 12345. This direct link does not test ECMP path selection. |
| Payload Length | 16 bits | 64: 8 bytes of ICMPv6 header plus the 56 data bytes selected with -s 56. There are no extension headers in this request. |
| Next Header | 8 bits | 58, so ICMPv6 starts immediately after the 40-byte base header. |
| Hop Limit | 8 bits | 37, selected with -t 37. It reaches the target unchanged because there is no router on the link. |
| Source Address | 128 bits | 2001:db8:106::1, the source's eth1 address. |
| Destination Address | 128 bits | 2001:db8:106::2, the target's eth1 address. |
The widths add to 320 bits, or 40 bytes. The captured Ethernet frame is 118 bytes: 14 bytes of Ethernet header + 40 bytes of IPv6 base header + 64 bytes of payload. The capture does not include an Ethernet FCS. Keep the frame size, IPv6 packet size, and Payload Length separate when reading a decode.
For the byte-by-byte view, the IPv6 header starts with 6b 80 30 39 00 40 3a 25. The first four bytes pack Version, Traffic Class, and Flow Label. Then 00 40 is Payload Length 64, 3a is Next Header 58, and 25 is Hop Limit 37. The two 16-byte addresses complete the base header. ICMPv6 begins at IPv6 offset 40, or offset 54 from the start of this Ethernet frame.
These are request values. The reply has its own Flow Label (0xba188) and Hop Limit (64); do not mix its fields into the request table.
Fragment Header: Next Header 44
The second test sent 2000 ping data bytes with -s 2000 -M dont. Here, -M dont allowed the Linux source to fragment the oversized request. IPv6 routers do not fragment packets: the source adds the Fragment Header, and the receiver reassembles the message. Both frames in fragment.pcap belong to this one Echo Request.
Frame 1, excerpted from the full tshark -V decode:
Internet Protocol Version 6, Src: 2001:db8:106::1, Dst: 2001:db8:106::2
0110 .... = Version: 6
.... 1011 1000 .... .... .... .... .... = Traffic Class: 0xb8 (DSCP: EF, ECN: Not-ECT)
.... 1011 10.. .... .... .... .... .... = Differentiated Services Codepoint: Expedited Forwarding (46)
.... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0)
.... 0000 0101 1011 1010 0000 = Flow Label: 0x05ba0
Payload Length: 1456
Next Header: Fragment Header for IPv6 (44)
Hop Limit: 37
...
Fragment Header for IPv6
Next header: ICMPv6 (58)
Reserved octet: 0x00
0000 0000 0000 0... = Offset: 0 (0 bytes)
.... .... .... .00. = Reserved bits: 0
.... .... .... ...1 = More Fragments: Yes
Identification: 0x78fb42f8
The base header now points to Fragment Header (44). Inside that extension header, Next Header points to ICMPv6 (58). Offset 0 marks the start of the message, and More Fragments is Yes.
Frame 2 carries the rest. Its decode shows the second offset and the completed reassembly:
Payload Length: 568
Next Header: Fragment Header for IPv6 (44)
Hop Limit: 37
...
Fragment Header for IPv6
Next header: ICMPv6 (58)
Reserved octet: 0x00
0000 0101 1010 1... = Offset: 181 (1448 bytes)
.... .... .... .00. = Reserved bits: 0
.... .... .... ...0 = More Fragments: No
Identification: 0x78fb42f8
[2 IPv6 Fragments (2008 bytes): #1(1448), #2(560)]
[Frame: 1, payload: 0-1447 (1448 bytes)]
[Frame: 2, payload: 1448-2007 (560 bytes)]
[Fragment count: 2]
[Reassembled IPv6 length: 2008]
Both fragments have identification 0x78fb42f8. The second offset is 181 in 8-byte units: 181 × 8 = 1448 bytes into the original ICMPv6 message. More Fragments is No, so this is the last fragment. Its data continues the message; it does not start another ICMPv6 header.
Payload Length includes the Fragment Header in each packet:
| Measured size | Fragment 1 | Fragment 2 |
|---|---|---|
| Fixed IPv6 base header | 40 bytes | 40 bytes |
| Fragment Header | 8 bytes | 8 bytes |
| Fragment data | 1448 bytes | 560 bytes |
| Payload Length | 1456 = 8 + 1448 | 568 = 8 + 560 |
| IPv6 packet size | 1496 = 40 + 1456 bytes | 608 = 40 + 568 bytes |
The receiver reassembles 1448 + 560 = 2008 bytes: an 8-byte ICMPv6 header plus the original 2000 ping data bytes. This is why “40-byte IPv6 header” needs the word *base*: extension headers add bytes after it, and those bytes belong to Payload Length.

This capture demonstrates source fragmentation on a direct link. It does not test routed Path MTU Discovery or ICMPv6 Packet Too Big behavior.
Why the Header Is Faster
Three reasons IPv6 forwarding is faster than IPv4 on similar hardware:
- Fixed header length. Routers know exactly where each field is; no IHL math.
- No checksum recomputation. Decrementing Hop Limit does not require updating the header.
- No options parsing on the fast path. Extension headers exist but are usually skipped on intermediate routers (only the destination examines Destination Options; only routers along the path examine Hop-by-Hop).
Combined with hardware acceleration in modern silicon, IPv6 typically forwards at line rate on any router that does IPv4 at line rate.
Summary
The IPv6 header is 40 bytes fixed: 4-bit Version, 8-bit Traffic Class, 20-bit Flow Label, 16-bit Payload Length, 8-bit Next Header, 8-bit Hop Limit, plus 128-bit source and destination addresses. Extension headers chain between the base header and the payload via Next Header values; common ones include Fragment, Routing, ESP, AH, and Destination Options.
The header is intentionally minimalist - simpler than IPv4, faster to parse, easier to hardware-accelerate. Master the field layout and the Next Header chain and you can read any IPv6 packet capture. Bookmark this article alongside the IPv6 cluster pillar.