In Wireshark 4.6, a service on TCP 8443 shows as TCP carrying Data; how is a payload dissector picked, and how do you fix it?
answer
- tables first, guesses second
- a table keyed by port number
- Data means nobody claimed it
- Analyze > Decode As, then Save
- tshark -d tcp.port==8443,<proto>
basics
~20 sWireshark offers the TCP payload to the dissector the tcp.port table maps to that port, then to heuristic dissectors; if none claims it, the bytes fall to Data. Analyze > Decode As maps port 8443 to the right dissector.
solid answer
~50 sMost dissectors register either in a **dissector table** keyed by a lower-layer value (`ethertype`, `ip.proto`, `tcp.port`, `udp.port`, `tls.port`) or as a **heuristic** that inspects the payload's first bytes. For a TCP payload, Wireshark 4.6 tries the dissector already pinned to the conversation, then any port changed with Decode As, then the default `tcp.port` entries (the server port seen in the SYN, then the lower port, then the higher), then the TCP heuristics, and finally `Data`. So `Data` on 8443 means no table entry and no heuristic recognised the bytes. The fix is **Analyze > Decode As…**: add an entry for TCP port 8443, set *Current* to the right protocol and press **Save**, which writes it to the profile's `decode_as_entries` file. For a one-off tshark run, `-d tcp.port==8443,http2` does the same. Once it decodes, that protocol's fields exist and can be filtered.
go deeper
Recall that Data means no dissector was chosen, and that Analyze > Decode As maps a port to a protocol. Know to press Save if the mapping must survive a restart.
Explain the selection order for a TCP payload: conversation dissector, Decode As ports, default port entries, heuristics, then Data. Show where the saved entry lives and the tshark -d equivalent.
Diagnose why a mapping only half-works: pinned conversations, segments TCP never passes up, TLS hiding the inner protocol. Make the setting reproducible for the team through a shared profile or a scripted tshark -d.
Weigh standardising service ports against shipping analysis profiles with Decode As entries, so incident responders are not decoding in-house services by hand under time pressure.
## What a dissector is A **dissector** is the piece of Wireshark that understands one protocol. It reads that protocol's header, adds named fields to the packet-details tree, and hands the remaining bytes to the next dissector up. A TCP packet over Ethernet is dissected as a chain: the Ethernet dissector reads its header and uses the type value 0x0800 to call IP; IP uses its protocol number to call TCP; TCP must then decide who gets the payload. When nobody is chosen, Wireshark shows the remainder as a **Data** layer of raw bytes. Seeing `Data` on a known service is therefore not a statement about the traffic. It is a statement that Wireshark did not know which dissector to call. ## The two ways a dissector registers | Mechanism | How it works | Typical keys | |---|---|---| | **Dissector table** (static) | A dissector registers under a value of a lower-layer field; the lower layer looks the value up | `ethertype`, `ip.proto`, `tcp.port`, `udp.port`, `tls.port`, `tls.alpn` | | **Heuristic list** | A dissector registers a test function; the lower layer asks each one whether the bytes look like its protocol | lists named after the carrier, such as `tcp` and `udp` | A dissector can also be called directly by name from another dissector, or attached to a **conversation** so that every later packet of one connection goes straight to it; both show up in the order below. Tables are fast and certain when the convention holds, and wrong when it does not: HTTP on a port HTTP never registered is invisible to the table. Heuristics cover that gap, but only for protocols that ship one and only when their test matches. `tshark -G dissector-tables` lists every table and whether it supports Decode As; `tshark -G decodes` lists the current port-to-protocol associations. ## The order for a TCP payload in Wireshark 4.6 The TCP dissector's selection routine tries, in this order: 1. A dissector already attached to the **conversation**, for example one a heuristic pinned earlier in the same connection. 2. Any port whose table entry was **changed with Decode As**: the server port seen in the SYN or SYN/ACK, then the lower port, then the higher. 3. The **heuristic** list, only if the TCP preference *Try heuristic sub-dissectors first* is on (it is off by default). 4. The **default** `tcp.port` entries: server port, then the lower port, then the higher. Preferring the lower port makes both directions pick the same dissector and favours well-known ports over ephemeral ones. 5. The **heuristic** list, in its normal position. 6. `Data`. Two practical consequences follow. TLS or plain HTTP/1.x on an odd port are usually still recognised, because the TLS and HTTP heuristics over TCP are enabled by default and match record headers or an `HTTP/1.` request or status line. What lands in `Data` is a protocol with no heuristic, a heuristic that is switched off, or one whose signature the capture never contained. ## Fixing it with Decode As - Open **Analyze > Decode As…**, or right-click a packet and choose Decode As so the entry is pre-filled from that packet. - The entry has a **Field** (here TCP port), a **Value** (8443), a read-only **Default** column showing what would normally be called, and **Current**, the dissector you want instead. - *Current* only offers protocols the carrier can carry directly: you cannot hand a TCP payload to the Ethernet dissector. - **OK** applies the mapping for this session; **Save** writes it to the `decode_as_entries` file of the current configuration profile. Unsaved entries are lost on exit or profile change. - *Current* may also be `(none)`, which stops a wrong dissector claiming a port and leaves the bytes as `Data`. - On the command line, `tshark -d tcp.port==8443,http2` applies the same override for one run; a range such as `tcp.port==8888-8890,http` also works, and an invalid selector makes tshark print the valid ones. A saved Decode As entry for a port is also applied to that protocol's own port-range preference where it has one. HTTP's default TCP range, for instance, is `80,3128,3132,5985,8080,8088,11371,1900,2869,2710`, so adding 8443 there is the other persistent route. ## What changes once it decodes The chosen dissector creates that protocol's **fields**, such as `http.request.method` or `http2.streamid`. Those names exist in a packet only when the dissector ran on it, so a filter on them silently matches nothing while the traffic is still `Data`. Decode As is an analysis setting, not an edit to the capture: the pcapng file is unchanged, and a colleague opening it with a different profile sees `Data` again. If the payload is TLS without keys, Decode As cannot reveal the inner protocol; decryption is a separate step.
- Decode As on port 8443 is set, yet some packets in that connection still show as Data. Why?Not every segment reaches a payload dissector. TCP hands keep-alive payload straight to `Data`, and with the TCP preference *Do not call subdissectors for error packets* (on by default) retransmitted or out-of-order segments are not passed up either. And if something attached a dissector to the conversation itself, such as a heuristic that matched or another protocol that set the connection up, that dissector is tried before any Decode As port.
- Should you use Decode As or edit the protocol's port preference?They feed the same `tcp.port` table. Decode As works for any protocol that supports it, offers `(none)` to suppress a wrong dissector, and is pre-filled from a selected packet. A protocol's port-range preference is convenient when it listens on several ports, and a saved Decode As entry for a port is applied to that preference anyway. Both live in the current profile, not in the capture file.
saying these in an interview costs you the question
- Wireshark identifies every protocol from content, so the port number never matters.
- Data in the packet list means the payload is encrypted.
- Pressing OK in Decode As keeps the mapping for the next session.
- Decode As rewrites the capture file, so colleagues see the same decoding.
- Any dissector can be chosen for any layer in Decode As.