DEV Community

Rasika Dangamuwa
Rasika Dangamuwa

Posted on

Why HAR File Analysis Fails in Production: 5 Network Logging Traps Every Engineer Hits

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"}"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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
  }
}
Enter fullscreen mode Exit fullscreen mode

Engineers writing custom HAR parsers often assume:
time = blocked + dns + connect + send + wait + receive

In practice, this formula breaks down for three reasons:

  1. HTTP/2 & HTTP/3 Multiplexing: Reused TCP connections set dns and connect to -1 (not applicable).
  2. TLS Overlap: The ssl timing is technically a subset of connect, not an additive phase. Adding ssl and connect together double-counts the TLS handshake.
  3. Queueing vs Execution: blocked measures 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"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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-json or SAX-style parsers) that emit individual entry objects 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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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

  1. Sanitize First: Strip bearer tokens, session cookies, and private form data before sharing logs.
  2. Handle Multiplexed Timings: Remember connect: -1 and avoid double-counting SSL handshake durations.
  3. Check Base64 Encodings: Decode compressed or binary payloads before parsing response bodies.
  4. 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)