The field names and filter syntax on this page are Wireshark’s own display-filter names, and the header fields are those defined in RFC 9110 and RFC 9112. The procedure is written to be followed on a live capture rather than read.
Have Wireshark open while you read. Do the six steps once on a real site, then work the exercises against your own capture rather than against the examples here — the whole point of the skill is reading a capture you have never seen.
Capture only traffic on a network you are authorised to monitor, and only your own traffic unless you have explicit permission. On most networks, capturing other people’s traffic is a violation of policy and in many places of law. Everything on this page is done on your own machine, watching your own browser.
What you are looking at#
Wireshark records the frames arriving at and leaving a network interface and decodes them. Its window has three panes, and knowing which is which turns the tool from intimidating to obvious:
| Pane | What it holds | What you do there |
|---|---|---|
| Packet list | One row per packet, with source, destination, protocol and summary | Find the packet you want |
| Packet detail | The selected packet decoded into nested protocol layers | Expand layers and read fields |
| Packet bytes | The raw bytes, in hex and ASCII | Confirm what a field really contains |
The detail pane is where the exam lives. It shows one packet as a stack of layers, outermost first, and that stack is the protocol stack you have been learning:
Frame — what the capture tool recorded
Ethernet II — link layer: MAC addresses
Internet Protocol Version 4 — network layer: IP addresses
Transmission Control Protocol — transport layer: ports, sequence numbers
Hypertext Transfer Protocol — application layer: the request or responseEach layer in the detail pane wraps the one below it. The HTTP message is the innermost item, carried inside a TCP segment, carried inside an IP packet, carried inside an Ethernet frame. Expanding the stack is a picture of encapsulation, which is worth looking at once for its own sake.
Vocabulary, before anything uses it#
| Term | What it means |
|---|---|
| Packet capture | A recording of the frames that crossed a network interface. |
| Interface | The network adapter being watched — Wi-Fi, Ethernet, or a virtual one. |
| Capture filter | A rule applied while recording, which discards non-matching traffic permanently. |
| Display filter | A rule applied to an existing capture, which hides non-matching packets without deleting them. |
| Promiscuous mode | An interface setting that accepts frames not addressed to this host. |
| Frame | The link-layer unit Wireshark records, containing everything above it. |
| Encapsulation | Each layer wrapping the layer above it in its own header. |
| Follow stream | A Wireshark command that reassembles a whole TCP conversation into readable text. |
| TLS | The encryption layer beneath HTTPS, which is what a capture shows instead of HTTP on a secure site. |
| QUIC | A transport running over UDP and used by HTTP/3, which will not appear as TCP or as HTTP in a capture. |
| Hard refresh | Reloading a page while bypassing the browser cache, so a request is actually sent. |
| Ephemeral port | The temporary high-numbered port the client picks for one connection. |
The hard part: getting plain HTTP at all#
Nearly every site is HTTPS. HTTPS is HTTP inside TLS, and TLS is encrypted, so a capture of a normal browsing session shows rows labelled TLSv1.3 carrying Application Data — and no HTTP whatsoever. Wireshark is working correctly; there is genuinely no readable HTTP there to find.
“No HTTP packets” almost never means Wireshark is broken. In order of likelihood: the site was HTTPS, so the traffic is TLS; or the browser served the page from its cache and never sent a request; or the connection used HTTP/3 over QUIC, which is UDP and will not match a TCP-based filter; or the wrong interface was selected. Check those four before changing anything else.
Three ways to get a capture that really contains HTTP, in order of reliability:
- Use a site that still serves plain HTTP. Several sites are maintained specifically for protocol teaching and are reachable over
http://. Type thehttp://prefix explicitly, because browsers addhttps://when you do not. - Run a web server on your own machine and request
http://localhost. Note that you must then capture on the loopback interface, not Wi-Fi, because the traffic never leaves the machine. - Request a URL that is known to redirect. The initial plain-HTTP request and its
301response are real HTTP, and they are enough to show a complete request and response pair.
And whichever you use, do a hard refresh. A browser that has the page cached will not send a request at all, and an empty capture after a page visibly loaded is nearly always this.
The capture, in six steps#
- Close what you can. Chat clients, mail clients, streaming tabs — each one adds traffic you will have to filter out. A quiet machine makes a readable capture.
- Pick the right interface. Wireshark’s opening screen lists interfaces with a live activity sparkline beside each. The one that is moving is the one carrying your traffic. Choose loopback only if you are requesting
localhost. - Start the capture before you browse, not after. This is the step people get backwards.
- Make the request. Go to the browser, type the
http://URL, and hard refresh. - Stop the capture as soon as the page has loaded. A capture left running for five minutes is a capture you will spend five minutes searching.
- Apply the display filter
httpand press Enter.
Filters worth knowing, and the difference between the two kinds:
| Filter | Kind | Shows |
|---|---|---|
http | Display | Every HTTP request and response in the capture |
http.request | Display | Requests only |
http.response | Display | Responses only |
http.host == "example.com" | Display | Only traffic for that host |
tcp.port == 80 | Display | Everything on port 80, including the TCP handshake |
tcp port 80 | Capture | Records only port 80 traffic and discards the rest |
Capture filters and display filters have different syntax and different consequences. A capture filter (tcp port 80) is applied while recording and what it excludes is gone forever. A display filter (tcp.port == 80) only hides rows, and clearing it brings everything back. Note the dot and the double equals in the display version. Start with display filters — you cannot lose data with them.
Reading the request#
Click a row whose Info column starts with GET. In the detail pane, expand Hypertext Transfer Protocol. You will see the request line first and then one row per header, in the order the browser sent them — which is exactly the message structure from the printed page, one line per row.
Wireshark adds three convenience rows that are not header fields, and knowing they are synthetic prevents confusion:
| Row | What it is |
|---|---|
[Full request URI: ...] | Wireshark joining the Host header and the path into one URL for you |
\r\n on its own | The blank line ending the headers — a real part of the message |
[Response in frame: N] | A cross-reference to the matching response, added by Wireshark |
Answering the standard questions from the detail pane:
| Question | Where the answer is |
|---|---|
| What method was used? | First word of the request line — GET, POST, HEAD |
| What host was visited? | The Host header. Not the request line, which holds only the path |
| What is the connection status? | The Connection header — keep-alive or close |
| What HTTP version? | Last field of the request line |
Answer from the header whose name matches the question, not from the value that looks plausible. Find Connection and read it; do not scan for something that looks like a status.
Reading the response#
With the http filter applied, the response is usually the next matching row, and Wireshark links them: the request detail contains [Response in frame: N], and the response contains [Request in frame: N]. Use those rather than guessing from timestamps.
Expand Hypertext Transfer Protocol on the response and the status line is the first row:
HTTP/1.1 200 OK\r\n
[Status Code: 200]
[Status Code Description: OK]
Response Phrase: OK| Question | Where the answer is |
|---|---|
| What is the status? | Status line — the code and its phrase, for example 200 OK |
| What HTTP version? | First field of the status line |
| What is the expiration date? | The Expires header — or Cache-Control: max-age if there is no Expires |
| When did the object last change? | The Last-Modified header |
| How big is the body? | The Content-Length header, in bytes |
Three headers carry dates and they mean different things. Date is when the server generated the response. Last-Modified is when the object last changed. Expires is when the copy goes stale. A question about an expiration date wants Expires, and if the capture has no Expires header the honest answer names Cache-Control: max-age instead and says the response carries no absolute expiry — which is a better answer than quoting the wrong header.
Follow → HTTP Stream on either packet reassembles the whole conversation into plain text, request in one colour and response in another. It is the fastest way to see the two messages as messages rather than as tree rows, and it is worth doing once even when it is not what a question asks for.
Worked example#
You have a capture and a filter of http shows nothing at all, although a page clearly loaded in the browser while the capture was running. Diagnose it.
Step 1 — Clear the filter and look at what is actually there. Do not adjust the filter yet. An empty result tells you nothing about what the capture contains; the unfiltered list tells you everything.
Step 2 — Read the Protocol column and match it to a cause. The column names the problem directly:
| What the Protocol column shows | What it means |
|---|---|
TLSv1.2 or TLSv1.3 | The site is HTTPS. The HTTP is inside encryption and cannot be read |
QUIC | HTTP/3 over UDP. There is no TCP connection and no plaintext HTTP |
TCP only, on port 80 | The connection was made but no request followed — usually a cached page |
| Almost nothing at all | Wrong interface, or loopback traffic captured on Wi-Fi |
Step 3 — Fix the cause, not the filter. Each of those four has a different fix, and changing the filter fixes none of them.
TLS → use an http:// site · cached → hard refresh
QUIC → use a plain-HTTP site · empty → change interface
Step 4 — Recapture with the fix in place, then apply http again. Getting a clean capture is the skill; reading it afterwards takes a minute.
It names what the capture did contain, explains why that is not HTTP, and states the fix. “It did not work” is not a diagnosis; “the capture shows TLS Application Data because the site is HTTPS, so I recaptured against a plain-HTTP URL” is.
Practice#
Work these against a capture you took yourself. Answers to 4 to 9 will differ from anyone else’s, which is the point — what is being tested is whether you can find the field.
- What is the difference between a capture filter and a display filter, and which is safer to experiment with?
- Name the five protocol layers you expect in the detail pane of an HTTP packet, outermost first.
- A filter of
httpreturns nothing. Give four possible causes and the fix for each. - Take a capture of a plain-HTTP page. What method does your request use, and where in the message did you read it?
- What host name did you visit, and which header carried it? Why is it not in the request line?
- What is the connection status in your request, and what does that value mean for the TCP connection?
- What is the status code and phrase of your response, and what class does the code belong to?
- What HTTP version does your response use? Which field of which line is it in?
- Does your response carry an
Expiresheader? If not, what is there instead and what does it mean? - Expand the TCP layer of your request. Which port is the server and which is the client, and how do you know?
Solutions#
For the questions about your own capture there is no answer key, and that is deliberate. Check yourself a different way: point at the exact row in the detail pane and say the field name out loud before reading the value. If you cannot name the field, you found the value by luck.
- Applied while recording versus applied afterwards. A capture filter is applied while recording and permanently discards traffic that does not match. A display filter is applied to a capture you already have and only hides rows, so clearing it brings everything back. Display filters are safer to experiment with, and they use a different syntax —
tcp.port == 80rather thantcp port 80. - Frame, Ethernet, IP, TCP, HTTP. Frame (what the capture tool recorded), Ethernet II (link layer, MAC addresses), Internet Protocol (network layer, IP addresses), Transmission Control Protocol (transport layer, ports), and Hypertext Transfer Protocol (application layer, the message itself). Each wraps the one after it.
- HTTPS, cache, QUIC, wrong interface. The site was HTTPS, so the traffic appears as TLS — use a plain-HTTP URL. The browser served the page from cache and sent no request — hard refresh. The connection used HTTP/3 over QUIC, which is UDP — use a site that speaks HTTP/1.1. Or the wrong interface was selected — pick the one showing activity, and use loopback only for
localhost. - The first word of the request line. Almost certainly GET, read from the first field of the request line in the HTTP layer of the detail pane. If you submitted a form it may be POST.
- The Host header. The
Hostheader carried it. It is not in the request line because the request line contains only the path portion of the URL; HTTP/1.1 requires the separateHostheader because one server with one IP address commonly serves many different websites. - The Connection header. Read the
Connectionheader.keep-alivemeans the client is asking for the TCP connection to stay open for further requests;closemeans it should be torn down after this exchange. In HTTP/1.1 staying open is the default in any case. - The status line, first line of the response. Read the code and phrase from the status line — commonly
200 OK, and301 Moved Permanentlyif you used a redirecting URL. The class is given by the first digit: 2xx success, 3xx redirection, 4xx client error, 5xx server error. - The first field of the status line. Usually
HTTP/1.1. It is the first field of the status line, which is the reverse of the request, where the version comes last. - Expires, or Cache-Control max-age. Many modern responses have no
Expiresheader and carryCache-Control: max-age=Ninstead, which gives a lifetime in seconds from the time of the response rather than an absolute date. Saying that explicitly is a better answer than quotingDateorLast-Modified, neither of which is an expiry. - Port 80 is the server. The server is the end using port 80, the well-known port for HTTP. The other port is a high-numbered ephemeral port your operating system chose for this one connection. In the request the pair reads client to 80; in the response it reads 80 back to the client.
Test-readiness checklist#
- ☐ I can choose the right interface and say why loopback is different.
- ☐ I can start a capture, make one request, and stop it without collecting a minute of noise.
- ☐ I can write a display filter for requests only, responses only, and one host.
- ☐ I can say which kind of filter destroys data and which only hides it.
- ☐ I can name the five layers in the detail pane and say which wraps which.
- ☐ I can find the method, host, version and connection status in a request without hunting.
- ☐ I can find the status code, version, expiry and content length in a response without hunting.
- ☐ I can explain why a capture of an HTTPS site shows no HTTP.
- ☐ I can diagnose an empty http filter by looking at the Protocol column first.
- ☐ I can say which end of a TCP conversation is the server from the port numbers alone.
When you screenshot a capture for submission, expand the layer you were asked about and make the text legible at full size. A screenshot of a collapsed tree shows that you found a packet, not that you read it — and the marks are for the fields, which have to be visible to be credited.
Frequently asked questions#
Why does Wireshark show no HTTP packets when I browse?
Most likely the site is HTTPS, so the traffic appears as TLS Application Data and the HTTP inside it is encrypted. The other common causes are the browser serving the page from cache so no request was sent, the connection using HTTP/3 over QUIC which is UDP, or the wrong interface being captured.
What is the difference between a capture filter and a display filter?
A capture filter is applied while recording and permanently discards non-matching traffic. A display filter is applied afterwards and only hides rows, so clearing it restores everything. They also use different syntax: tcp port 80 for a capture filter, tcp.port == 80 for a display filter.
Where do I find the host name in a captured HTTP request?
In the Host header inside the HTTP layer of the packet detail pane. The request line contains only the path part of the URL, so the host name is never there. Wireshark also synthesises a Full request URI row that joins the two.
How do I find the response that matches a request?
Expand the HTTP layer of the request and look for the Response in frame cross-reference Wireshark adds, then click it. The response carries the mirror-image Request in frame row. Follow HTTP Stream shows both messages together as readable text.
What if the response has no Expires header?
Many servers use Cache-Control with a max-age in seconds instead, which expresses a lifetime rather than an absolute date. Say so explicitly rather than substituting Date or Last-Modified, because neither of those is an expiry and quoting one as if it were is a clear error.
Something here not clear? A topic you wish we covered? Tell us. We read every message, and a request is the fastest way to get a guide written.
Test yourself in the free Kestrel Exams app
Topic-selectable practice — offline, no ads, no account. A networking question bank is not built yet; every other subject is open.
Choose your subject →