At a glance

"Can Hollowport see X" has more than one honest answer, because seeing a connection, reading its metadata, and reading its actual content are three different things. A certificate-pinned HTTPS connection isn't simply "invisible" — its content is unreadable, but its destination is usually still known. DNS-over-TLS is a harder boundary than that: neither its content nor, typically, its destination is visible. Collapsing all of this into "fully / partially / not visible" would hide exactly the distinction that matters, so here's the specific tier each traffic type actually falls into:

HTTP/1.1 & HTTP/2 (not pinned)HTTP contents available
HTTP/3 / QUIC (not pinned)HTTP contents available
WebSockets (enabled per host)HTTP contents available
DNS-over-HTTPS (DoH)HTTP contents available
Certificate-pinned HTTPS
DNS-over-TLS (DoT)Not intercepted
Traffic outside ports 443 / 80Not intercepted

HTTP contents available — full request/response, headers, body. Connection metadata available — hostname, timing, and that a connection happened, but not its content. Not intercepted — Hollowport doesn't touch this traffic at all. Hostname attribution is a separate axis from all three of these — see below.

HTTP/1.1 & HTTP/2

Hollowport terminates the client TLS connection with its own minted certificate, opens a genuinely separate, verified TLS connection upstream, and relays the plaintext HTTP in both directions — full headers, full body, full timing, for both HTTP/1.1 and HTTP/2 including HTTP/2's multiplexed streams. This is a real man-in-the-middle you've explicitly authorized, not a partial capture: the fidelity is the same as a browser's own dev tools show for its own traffic. See why HTTP/2 traffic looks different for what multiplexing actually changes.

HTTP/3 / QUIC

HTTP/3 is decrypted end-to-end, on the same terms as HTTP/1.1 and HTTP/2 — the same real interception, the same complete headers and body, for connections that aren't certificate-pinned. See Features for how this fits alongside HTTP/1.1 and HTTP/2 capture.

WebSockets

WebSocket frame decoding is opt-in per host, not automatic. Turn it on once for a host and individual frames — sent and received — appear the same way HTTP requests do in Capture. A host without it enabled still shows the underlying connection; its frames simply aren't decoded until you ask for them. See GraphQL and WebSocket inspection for the full walkthrough.

TLS / SNI visibility

Even for a connection Hollowport can't decrypt — most commonly a pinned app — it can almost always still name the destination. TLS's ClientHello includes the server's hostname (SNI, Server Name Indication) in plain text, before any certificate is exchanged, so the server knows which certificate to present. Hollowport reads that same plaintext hostname, which is how it can label a pinned connection by name even though its content stays opaque. What you get for an undecryptable connection: hostname, timing, and that it happened. What you don't get: the request or response content. See what actually happens during a TLS handshake for the underlying mechanics.

Certificate pinning

An app that pins its certificate checks the server's certificate (or public key) against a value it already knows, rather than trusting whatever the device's certificate store trusts — so it rejects Hollowport's certificate the same way it would reject any unexpected one. Hollowport detects this specific failure and labels it as a pinning rejection, distinct from an ordinary decryption problem, and offers a bypass for that host: Hollowport stops attempting to decrypt that connection, so the app keeps working, but nothing about that traffic becomes readable. This is a deliberate property of TLS pinning, not a gap in Hollowport — no on-device or off-device interception tool can read pinned traffic without modifying the app itself. Banking apps and Apple's own push notifications and iCloud Private Relay are the most common examples. Related: the FAQ's short answer, Certificate Setup, and how HTTPS interception actually works.

DNS-over-HTTPS (DoH)

DoH is decoded, not just passed through as opaque HTTPS. Hollowport recognizes DoH request and response bodies and decodes them into actual DNS records — questions, answers (A, AAAA, CNAME, NS, SOA, MX, TXT), and TTLs — the same way it decodes GraphQL and gRPC bodies, whether the wire format is the binary application/dns-message type or plain JSON. One boundary worth knowing: a GET-style DoH request that encodes its query in a ?dns= URL parameter is visible as plain text but isn't parsed into structured records — only request and response bodies are decoded.

DNS-over-TLS (DoT)

DoT is not intercepted at all, and it's a harder boundary than certificate pinning in a specific way: pinning is an interception attempt that the app's own certificate check then rejects, while DoT is never offered to Hollowport's interception layer in the first place — Hollowport's interception is scoped to ports 443 and 80, and DoT's port, 853, is routed straight through, untouched. That routing-level exclusion is also why DoT loses hostname naming where a pinned connection doesn't: hostname sniffing itself is scoped to port 443, so a DoT connection shows up, if at all, as a bare IP address and port, not a hostname.

Hostname & IP attribution

Hollowport fills in hostnames for many bare-IP connections by correlating them, within the same capture session, against other traffic that did reveal the hostname. This is deliberately best-effort, not certainty — stated plainly rather than implied to be more reliable than it is. It cannot work when there's no session-local hostname to correlate against — most plainly when an app resolves its own DNS over DoT, which is invisible to Hollowport entirely (see above), so there's nothing to correlate from; also when an app connects to a hardcoded IP address, or reuses a name that was resolved before the capture session started. DoH is a subtler case: the DNS exchange itself is fully readable as its own captured request, but that decoded content isn't wired into this separate correlation engine, which runs on the device's own live DNS queries and TLS handshakes rather than on already-decoded flow content — so reading a DoH response doesn't retroactively attach its answer to a later, separate connection made to the address it resolved. In any of these cases, the connection shows as a bare IP, honestly, rather than a guessed hostname.

Platform & security boundaries

Some limitations here aren't about Hollowport's own implementation at all — they're the operating system or an organization's policy. On a company- or school-managed device, installing a VPN configuration or trusting a custom certificate authority may be restricted, or may require your IT admin's approval; that's a management control, not something any app can override. See the FAQ for the specific MDM question, and Installing Hollowport for what to check first.

A note on precision

Every distinction on this page — content vs. metadata vs. nothing, interception vs. attribution, a platform boundary vs. an implementation gap — exists because conflating them would make Hollowport sound either more capable or more limited than it actually is. This page is meant to be the specific, checkable answer, and it'll be updated as capability changes rather than left to drift from what the app actually does.