What a Healthy Capture Looks Like
This guide shows what successful Qtap captures look like for different binaries and scenarios. Use these patterns as a reference when troubleshooting capture issues.
Understanding Healthy Captures
A healthy Qtap capture successfully:
✅ Detects the TLS handshake (SNI, TLS version)
✅ Identifies the HTTP protocol (http1, http2, http3)
✅ Captures process metadata (PID, binary path)
✅ Parses HTTP request/response headers and body
✅ Reports accurate byte counts and duration
Key indicator: "l7Protocol": "http1" or "http2" (NOT "other")
Quick Reference: Healthy Capture Checklist
When reviewing Qtap logs, a healthy capture shows:
If ANY of these are missing, investigate further with --bpf-trace.
curl: HTTP/2 over HTTPS
Complete HTTP Transaction JSON
{
"metadata": {
"process_id": "160239",
"process_exe": "/usr/bin/curl",
"bytes_sent": 41,
"bytes_received": 395,
"connection_id": "d3t55gg7p3qr49f8485g",
"endpoint_id": "httpbin.org"
},
"request": {
"method": "GET",
"url": "https://httpbin.org/get",
"scheme": "https",
"path": "/get",
"authority": "httpbin.org",
"protocol": "http2",
"request_id": "d3t55gg7p3qr49f84870",
"user_agent": "curl/8.10.1",
"headers": {
":authority": "httpbin.org",
":method": "GET",
":path": "/get",
":scheme": "https",
"Accept": "*/*",
"User-Agent": "curl/8.10.1"
}
},
"response": {
"status": 200,
"content_type": "application/json",
"headers": {
":status": "200",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Origin": "*",
"Content-Length": "255",
"Content-Type": "application/json",
"Date": "Thu, 23 Oct 2025 16:07:40 GMT",
"Server": "gunicorn/19.9.0"
},
"body": "ewogICJhcmdzIjoge30sIAog..."
},
"transaction_time": "2025-10-23T16:07:41.023379679Z",
"duration_ms": 10731,
"direction": "egress-external"
}Debug Log Indicators (curl)
TLS Handshake Detection:
processing tls handshake event
"exe": "/usr/bin/curl"
"SNI":"httpbin.org"
"Version":772 # TLS 1.3
"ALPNs":["h2","http/1.1"]Protocol Detection:
processing protocol event
"exe": "/usr/bin/curl"
"Protocol":"http2"
"IsTLS":trueConnection Metadata:
event store submission
"l7Protocol":"http2" ✅ NOT "other"
"tlsProbeTypesDetected":["openssl","openssl",...]
"tlsVersion":772
"bytesSent":901
"bytesReceived":4867Connection Report:
connection report
"gotTLSClientHelloEvent": true ✅
"gotProtocolEvent": true ✅
"dataEventCount": 6 ✅ Non-zero
"handler": "raw"
"strategy": "observe"wget: HTTP/1.1 over HTTPS
Debug Log Indicators (wget)
TLS Handshake:
processing tls handshake event
"exe": "/usr/bin/wget"
"SNI":"httpbin.org"
"Version":772
"ALPNs":null # wget doesn't advertise ALPNProtocol Detection:
processing protocol event
"exe": "/usr/bin/wget"
"Protocol":"http1" ✅ HTTP/1.1 detected
"IsTLS":trueHTTP Request Captured:
http request
"exe": "/usr/bin/wget"
"protocol": "http1"
"is_tls": true
"request": {
"Method":"GET"
"RequestURI":"/headers"
"Proto":"HTTP/1.1"
"Host":"httpbin.org"
"Headers": {
"Accept":["*/*"]
"User-Agent":["Wget/1.25.0"]
"Connection":["Keep-Alive"]
}
}HTTP Response Captured:
http response
"exe": "/usr/bin/wget"
"protocol": "http1"
"status_code": 200
"status": "OK"
"version": "HTTP/1.1"Python requests: HTTP/1.1 over HTTPS
Debug Log Indicators (Python)
TLS Handshake:
processing tls handshake event
"exe": "/usr/local/bin/python3.11"
"SNI":"httpbin.org"
"Version":772Protocol Detection:
processing protocol event
"exe": "/usr/local/bin/python3.11"
"Protocol":"http1"
"IsTLS":trueHTTP Transaction:
http request
"exe": "/usr/local/bin/python3.11"
"protocol": "http1"
"is_tls": true
"request": {
"Method":"GET"
"Host":"httpbin.org"
"Headers": {
"User-Agent":["python-requests/2.31.0"]
"Accept-Encoding":["gzip, deflate"]
}
}Debug Log Patterns
Healthy Capture Sequence
Socket Connection
socket connect event "conn_id": "..." "cookie": 12345 "exe": "/usr/bin/curl"TLS Detection (for HTTPS)
processing tls handshake event "SNI": "example.com" "Version": 772 # TLS 1.3Protocol Detection
processing protocol event "Protocol": "http2" | "http1" "IsTLS": trueHTTP Capture
object store submission "artifact": { "type": "http_transaction" "contentType": "application/json" "bytes": 1237 }Connection Finalization
socket close event "write_bytes": 901 "read_bytes": 4867 connection report "gotTLSClientHelloEvent": true "gotProtocolEvent": true "dataEventCount": 6
Key Fields to Check
✅ Success Indicators
"l7Protocol": "http1"or"http2"(NOT "other")"tlsProbeTypesDetected": ["openssl", ...]for HTTPS"gotTLSClientHelloEvent": truefor HTTPS"gotProtocolEvent": true"dataEventCount": > 0"bytesSent": > 0and"bytesReceived": > 0
❌ Failure Indicators
"l7Protocol": "other"- HTTP parsing failed"gotProtocolEvent": false- Protocol not detected"dataEventCount": 0- No data captured"write_bytes": 0, "read_bytes": 0- No traffic seen
BPF Trace Patterns
When to Use BPF Trace
Use --bpf-trace for deep troubleshooting of capture issues. See BPF Trace - Advanced Debugging for complete details.
--bpf-trace="mod:socket,exe.contains:curl"What it shows:
Individual syscall invocations (read, write, writev)
File descriptor (FD) numbers per operation
Data transfer sizes per syscall
TLS/SSL detection decisions per-FD
Healthy BPF Trace Example (curl)
Connection Metadata
event store submission
"connectionId": "d3t57dg7p3qra5r14cg0"
"endpointId": "httpbin.org"
"tlsProbeTypesDetected": ["openssl","openssl","openssl","openssl","openssl"]
"l7Protocol": "http2" ✅
"tlsVersion": 772
"socketProtocol": "tcp"
"bytesSent": 901
"bytesReceived": 4867HTTP Transaction Artifact
object store submission
"artifact": {
"type": "http_transaction"
"contentType": "application/json"
"bytes": 1237
"connectionId": "d3t57dg7p3qra5r14cg0"
"endpointId": "httpbin.org"
}Troubleshooting: What to Look For
Problem: HTTP Parsing Fails (l7Protocol: "other")
l7Protocol: "other")Check:
Was TLS detected? Look for
tlsProbeTypesDetectedWas protocol detected? Check
gotProtocolEvent: trueWas data captured? Check
dataEventCount > 0
Common causes:
Non-standard HTTP libraries (custom TLS wrappers)
Binary not using OpenSSL/BoringSSL (see
tlsProbeTypesDetected)Compression or encryption before TLS layer
Problem: No Capture at All
Check:
Is process filtered? Look for filter matches in debug logs
Is Qtap running? Check for
eBPF program loaded and listeningIs traffic direction captured? Verify
directionconfig matches traffic
Debug command:
docker logs qtap-container 2>&1 | grep -E "exe|protocol|l7Protocol"Problem: Missing Headers or Body
Check capture level:
none: No capturesummary: Basic info only (no headers/body)details: Headers included (no body)full: Everything (headers + body)
Verify plugin config:
plugins:
- type: http_capture
config:
level: full # Must be 'full' to see bodyProblem: Zero Bytes Captured
Check:
Connection report:
write_bytesandread_bytesshould be > 0Socket close event: Should show non-zero byte counts
BPF trace: Look for syscall data transfer events
Common causes:
Qtap started after traffic (must start before)
Connection reused from before Qtap started
Traffic on different network interface
Additional Resources
BPF Trace Deep Dive: See BPF Trace - Advanced Debugging for complete BPF trace field reference
Configuration Examples: See Configuration Examples
Traffic Processing with Plugins: See Traffic Processing with Plugins
Last updated