What is a heuristic dissector in Wireshark 4.6, and why might one miss traffic it should recognise or claim traffic it should not?
answer
- a guess instead of a port
- first bytes, then pin the conversation
- a signature the capture never saw
- registered ports are tried first
- Enabled Protocols lists heuristic entries
basics
~20 sA heuristic dissector recognises its protocol from the payload's first bytes rather than a port. It misses when it is disabled, a registered port is tried first, or its signature was never captured; it misclaims when unrelated bytes happen to fit.
solid answer
~50 sA heuristic dissector registers a test on a carrier's heuristic list (for TCP, `tcp`); when no port entry claims a payload, Wireshark asks each enabled test whether the bytes look like its protocol, and a match usually pins the conversation to that dissector. It **misses** when it is disabled by default (the user guide's example is RTP over UDP), when a registered port dissector runs first, or when its signature is not in the capture: HTTP/2 over TCP is only recognised by the connection preface `PRI * HTTP/2.0`, so a capture that starts after a long-lived connection opened shows `Data`. It **misclaims** when random bytes pass a weak test, worse with *Try heuristic sub-dissectors first* on. Entries are toggled in **Analyze > Enabled Protocols**, saved to the profile's `heuristic_protos` file, or set per run with `--enable-heuristic` / `--disable-heuristic`; `tshark -G heuristic-decodes` shows each one's state.
go deeper
Recall that some dissectors recognise a protocol from its first bytes instead of a port, and that these heuristic entries are listed under Analyze > Enabled Protocols.
Explain where heuristics sit in the order after port tables, how a match pins the conversation, and the three ways a heuristic misses: disabled, port taken, signature not captured.
Diagnose a missing or wrong decode from evidence: check heuristic state with tshark -G heuristic-decodes, spot a capture that began after the preface, and choose Decode As over loosening heuristics.
Decide how much guessing an analysis profile should allow: broad heuristics surface unknown services, but false positives mislead responders, so curated profiles trade discovery for trustworthy decodes.
## Static registration versus heuristics Wireshark finds the next dissector in two ways. A **static** registration ties a dissector to a value in a lower layer, such as TCP port 80 for HTTP or Ethernet type 0x0800 for IP. A **heuristic** registration ties a test function to a carrier's heuristic list, so the dissector can be found where no convention exists: a protocol on an arbitrary port, or one that rides inside another protocol without a type field. Each heuristic has a **short name** made of protocol and carrier, such as `http_tcp`, `tls_tcp`, `http2_tcp`, `dns_udp` or `rtp_udp`. ## How a heuristic decides - The carrier calls heuristics only after its port table has failed, unless the carrier's preference *Try heuristic sub-dissectors first* is on. TCP and UDP both have that preference, and it is off by default. - Each enabled heuristic looks at the first bytes and returns yes or no. A good test checks several things at once: a magic value, a type byte within range, a plausible length. - The first heuristic to say yes dissects the packet, and well-written ones attach themselves to the **conversation**. Later packets in that connection go straight to the same dissector without being tested again. - The pin applies from the matching frame onward. Packets of the same connection that were tested before the first match stay as they were, which is why the opening packets of a capture sometimes show `Data` and later ones decode. - If every heuristic says no, the payload falls to `Data`. ## Why a heuristic misses | Cause | Example | Fix | |---|---|---| | Disabled by default | RTP over UDP: the user guide says to enable `rtp_udp` before Wireshark will try UDP packets as RTP | Tick it under Analyze > Enabled Protocols, or `--enable-heuristic rtp_udp` | | Signature not captured | The HTTP/2-over-TCP heuristic only matches the client connection preface `PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n`; a long-lived cleartext HTTP/2 connection captured mid-stream never shows it | Decode As the port to HTTP2 | | A port dissector runs first | RTP on a port registered to another protocol: the user guide notes the RTP heuristic ignores well-known ports | Decode As that port, or turn on *Try heuristic sub-dissectors first* | | Protocol disabled | Disabling a protocol also skips all of its heuristic entries | Re-enable the protocol | | No heuristic exists | Many protocols register only by port | Decode As, or a dissector of your own | The preface case is common with long-lived gRPC or other cleartext HTTP/2 connections, because the capture almost always starts long after the connection did. Compare plain HTTP/1.x: its TCP heuristic accepts any segment whose first line starts or ends with `HTTP/1.`, so a mid-stream capture still finds it on the next request or response. ## Why a heuristic misclaims A heuristic is a guess, and weak guesses produce **false positives**. The user guide warns that with the RTP heuristic enabled, more UDP packets decode as RTP than really are, and that turning on *Try heuristic sub-dissectors first* raises the false-positive rate further, sharply so on a capture of a whole network. Because a match pins the conversation, one wrong guess colours an entire connection. Signs of a misclaim are a protocol you do not run appearing in the Protocol column, or a burst of malformed entries for a protocol that should not be there. ## Controlling heuristics 1. **Analyze > Enabled Protocols** lists heuristic entries as subtrees under their protocol and can filter the list to heuristic dissectors only. Unticking one removes it from the heuristic process; the protocol can still be reached through its static registrations. 2. Saving the dialog writes heuristic choices to the `heuristic_protos` file in the current profile. 3. For one tshark or Wireshark run, `--enable-heuristic <short_name>` and `--disable-heuristic <short_name>` override the profile. 4. `tshark -G heuristic-decodes` prints each heuristic's carrier list, name, whether it is enabled now, whether it is enabled by default, and its short name, which is the quickest way to answer "is this heuristic even on?". When a heuristic is the wrong tool, for instance because the signature only appears at connection start, **Decode As** on the port is the reliable fix: changed ports are tried before any heuristic. ## A worked diagnosis A cleartext HTTP/2 service on port 8443 shows as `Data`. Work through it in order: 1. Open Analyze > Decode As and add an entry for the port: the read-only *Default* column shows whether any dissector is registered there. Nothing is. 2. Run `tshark -G heuristic-decodes` and find the HTTP/2-over-TCP line: enabled now and enabled by default, so the heuristic is not switched off. 3. Look at when the capture began against when the connection opened. No SYN for the connection is in the file, so the preface was sent before capturing started. 4. Conclude the heuristic never had its signature, map the port to HTTP2 with Decode As, and press Save so the next capture of that service decodes immediately.
- Why not simply turn on Try heuristic sub-dissectors first for TCP on every capture?Because heuristics then run before the default port entries for every segment, so any weak test can steal traffic from the dissector registered on its proper port, and a single false match pins the whole conversation. The user guide warns the false-positive rate climbs on whole-network captures. Ports changed with Decode As still go first, so a targeted Decode As is the safer tool.
- How do you check from the command line whether a given heuristic is active in your profile?Run `tshark -G heuristic-decodes`. Each line gives the heuristic list such as `tcp`, the decoder name, whether it is enabled now (T or F), whether it is enabled by default, and the short name to pass to `--enable-heuristic` or `--disable-heuristic`.
saying these in an interview costs you the question
- Every heuristic dissector is enabled by default, so enabling one never changes anything.
- Heuristics always run before port-based dissectors.
- A heuristic re-tests every packet independently, so one false match cannot spread.
- HTTP/2 over cleartext TCP can never be decoded, only HTTP/2 inside TLS.
- Unticking a heuristic entry stops that protocol from appearing anywhere.