When a subtle production bug only reproduces for a specific customer, the standard triage procedure is universal: open browser DevTools, reproduce the workflow, export an HTTP Archive (.har) file, and upload it for engineering to inspect.
Because HAR files capture the exact sequence of HTTP requests, response headers, status codes, and timing metrics, they provide an unmatched timeline of what actually happened over the wire. However, parsing and debugging raw HAR logs in production environments is fraught with subtle traps—ranging from catastrophic secret leakage to broken timing math and browser memory crashes.
Here are 5 common HAR traps every engineer should know and how to handle them properly.
1. The Accidental Secret Leak (Bearer Tokens, Cookies & Query Strings)
A standard HAR file is an unencrypted, plaintext JSON archive of every HTTP transaction recorded during the session. When developers ask customers or colleagues to export a HAR to debug a failing API call, the archive records all active network traffic—including sensitive credentials across all open origins.
Look at a typical HAR request entry:
{
"request": {
"method": "POST",
"url": "https://api.example.com/v1/billing/checkout",
"headers": [
{ "name": "Authorization", "value": "Bearer eyJhbGciOi..." },
{ "name": "Cookie", "value": "session_id=s%3A918f4a...; csrf_token=ab82..." }
],
"postData": {
"mimeType": "application/json",
"text": "{"card_token":"tok_1N...","ssn_last4":"1234"}"
}
}
}
If this .har file is attached to a public Jira ticket, uploaded to an unverified third-party web tool, or shared in a Slack channel, any observer now has active session tokens, OAuth bearer keys, and sensitive user payloads.
The Fix: Before ingesting or sharing HAR files, run an automated redaction pass over known sensitive headers (Authorization, Cookie, Set-Cookie, X-Api-Key) and POST body JSON fields.
2. Waterfall Math Discrepancies (time vs Sum of timings)
In the HAR 1.2 specification, each entry contains an overall time float (in milliseconds) and a breakdown object named timings:
{
"time": 142.5,
"timings": {
"blocked": 12.1,
"dns": -1,
"connect": -1,
"ssl": -1,
"send": 0.4,
"wait": 125.0,
"receive": 5.0
}
}
Engineers writing custom HAR parsers often assume:
time = blocked + dns + connect + send + wait + receive
In practice, this formula breaks down for three reasons:
-
HTTP/2 & HTTP/3 Multiplexing: Reused TCP connections set
dnsandconnectto-1(not applicable). -
TLS Overlap: The
ssltiming is technically a subset ofconnect, not an additive phase. Addingsslandconnecttogether double-counts the TLS handshake. -
Queueing vs Execution:
blockedmeasures browser socket queue wait time.
If you need a quick, client-side way to inspect requests, timings, and headers without uploading sensitive traffic logs to a third-party server, Nutilz HAR Analyzer parses and renders the waterfall entirely in-browser.
3. Base64 vs Plain Text Body Encoding
When inspecting API responses or downloaded resources, developers look at entry.response.content.text. But if the server returned gzipped assets, protobuf binaries, images, or compressed JSON, browsers encode the data in Base64:
{
"response": {
"status": 200,
"content": {
"size": 48201,
"mimeType": "application/octet-stream",
"text": "H4sICDx1tGYAA3Jlc3BvbnNlLmpzb24A...",
"encoding": "base64"
}
}
}
If your parser naively calls JSON.parse(entry.response.content.text) without verifying content.encoding === 'base64', it will throw a syntax error on binary and compressed payloads. Always check the encoding field before attempting string manipulation or JSON parsing.
4. Memory Heap Crashes on Large SPA Captures
Single-page applications (SPAs) that stream data via WebSockets, Server-Sent Events (SSE), or poll REST endpoints every few seconds generate enormous HAR files. A 5-minute capture session can easily yield a 250MB to 500MB .har file.
Calling JSON.parse() on a 300MB JSON string in Node.js or browser JavaScript often spikes memory usage to 2GB–3GB due to AST object allocations, triggering an Out of Memory (OOM) crash.
To process large archives safely:
- Use streaming JSON parsers (like
stream-jsonor SAX-style parsers) that emit individualentryobjects one by one. - Filter out non-essential binary assets (images, fonts) before heavy DOM rendering.
5. Silent Client-Side Drops (status: 0 & CORS Errors)
Not every entry in a HAR file represents a completed HTTP exchange. When a request is blocked by a browser ad blocker, an invalid CSP directive, or a rejected CORS preflight, DevTools records the entry with status: 0 and empty response headers:
{
"request": { "method": "GET", "url": "https://analytics.thirdparty.com/track" },
"response": {
"status": 0,
"statusText": "",
"headers": [],
"content": { "size": 0, "mimeType": "x-unknown" },
"_error": "net::ERR_BLOCKED_BY_CLIENT"
}
}
Treating status: 0 as a backend 500 server error leads to false-positive alerts. Check the browser-specific _error or error state before blaming backend infrastructure.
Summary Checklist for Working with HAR Files
- Sanitize First: Strip bearer tokens, session cookies, and private form data before sharing logs.
-
Handle Multiplexed Timings: Remember
connect: -1and avoid double-counting SSL handshake durations. - Check Base64 Encodings: Decode compressed or binary payloads before parsing response bodies.
-
Beware of Memory Spikes: Stream large archives instead of running synchronous
JSON.parse().
For local analysis without server-side data ingestion, tools like Nutilz HAR Analyzer make inspecting HTTP waterfalls and headers fast and secure.
Top comments (0)