What is a HAR file? How to make, read and share one safely

TL;DR

A HAR file (HTTP Archive) is a JSON file that logs every network request a browser tab made: the URL, the request and response headers, cookies, status codes, timings and usually the response bodies. Browsers export it from their developer tools, and support teams use it to see exactly what failed between your browser and their servers.

In this guide

It's plain text, so any editor will open it. It's also big. A couple of minutes on a modern web app produces hundreds of entries, and most of them are fonts, images and analytics pings that nobody will ever read.

How to get a HAR file in Chrome, Firefox, Edge and Safari

Every browser works the same way. You open the developer tools, switch to the Network tab, reproduce the problem and export. The step people miss is keeping the log across page loads. Without it, the recording resets the moment the page navigates, and the request that broke disappears with it.

Open the Network tab
F12, or Cmd+Option+I on a Mac, then Network
Keep the log
Tick "Preserve log"
Export
The download arrow in the Network toolbar

Open the Network tab before you start, then go through the steps from just before the point where things break. Ten seconds recorded around the failure beats ten minutes of browsing. The developer has to find the needle either way.

How to open and read a HAR file

The easiest way to open a HAR file is to drag it onto the Network tab of Chrome's developer tools. It loads exactly like a live recording, and the file never leaves your machine. If you'd rather use a web page, our HAR analyzer lists the failed requests and flags secrets without uploading the file, and Google's HAR Analyzer works too.

Reading one is mostly knowing where to look. I start with failures: anything with a 4xx or 5xx status, plus status 0, which means the request never finished (blocked by CORS, an ad blocker or a dropped connection). Then I read the response body of the first failure. Errors cascade, and the first one usually explains the ones after it. After that come timings, because one request that takes 30 seconds explains "the page just hangs" better than any screenshot. Last are redirect chains, which are where login loops live.

If you have jq installed, two one-liners get you most of the way. This one lists every failed request:

Shell
jq -r '.log.entries[]  | select(.response.status >= 400 or .response.status == 0)  | "\(.response.status) \(.request.method) \(.request.url)"' session.har

And this one shows the five slowest:

Shell
jq -r '.log.entries | sort_by(-.time) | .[:5][]  | "\(.time | round)ms \(.request.url)"' session.har

Is it safe to share a HAR file?

Not as a raw export. A HAR file can contain your cookies, authorization headers and session tokens, and anyone holding a live session token can act as you until it expires. Recent Chrome versions strip cookies and auth headers by default, but tokens in URLs, request bodies and custom headers still get through. Check the file before you send it.

This isn't a theoretical risk. Between 28 September and 17 October 2023, an attacker had access to Okta's support case system and the files that 134 customers had uploaded for troubleshooting. According to Okta, some of those were HAR files with session tokens in them, and the attacker used the tokens to hijack sessions at five customers. Those customers had done exactly what support asked them to do.

Chrome and other Chromium browsers have exported a sanitized HAR by default since version 130, which drops the Cookie, Set-Cookie and Authorization headers. The full version is still there behind a setting under the developer tools' Network preferences. That closes the most common leak. It doesn't catch an API key in a query string, a token in a custom header like X-Auth-Token, or a password inside a form post. Don't assume other browsers sanitize anything.

To clean a file yourself, this removes cookies and the usual auth headers from every entry:

Shell
jq '.log.entries |= map(  .request.cookies = [] | .response.cookies = []  | .request.headers |= map(select(.name | ascii_downcase      | IN("cookie", "authorization", "x-api-key", "x-auth-token") | not))  | .response.headers |= map(select(.name | ascii_downcase      | IN("set-cookie") | not)))' session.har > session.clean.har

Then search what's left for anything that still looks like a credential:

Shell
grep -oiE '(token|bearer|api[_-]?key|session)[^"]{0,40}' session.clean.har | sort -u

Google's open source har-sanitizer does the same thing through a web page and also handles query strings and post parameters. If you'd rather not touch a terminal at all, the HAR analyzer runs both steps in your browser and hands you a redacted copy. No sanitizer is perfect, and that includes mine. Read what's left before you trust the file.

One more habit that costs nothing: once support has the file, sign out of the account you recorded. On most apps that ends the session, and every token in the file goes dead with it.

For support teams

Most people searching for this were asked for a HAR file. If you work in support and you're the one asking, the Okta breach is worth a minute of your team's time. The files that leaked were sitting in a support system, exactly where customers had been told to send them.

Three habits cover most of the risk:

  • Ask for the four facts in the next section first, and only ask for a HAR when they aren't enough.
  • When you do need one, ask for a redacted copy. Send the customer to a HAR checker that runs in their browser and they can make one in a minute.
  • Treat every HAR like a password. Keep it out of shared tickets and chat, delete it when the case closes, and ask the customer to sign out once you have it.

What should support ask for instead of a HAR file?

Usually just the one request that failed: its method, URL, status, response body and the time it happened, plus the browser console error if there was one. That's almost always enough to find the bug in server logs, and none of it can sign anyone in.

Ask forWhy it helps
Method, URL and status of the failing requestNarrows the problem to one endpoint
Its response bodyUsually contains the real error message
The console error and stack tracePoints at a file and a line
The time it happened and the browserLets you find it in server logs

I think a whole HAR is the wrong default for most support requests. It asks a customer to run developer tools, then hands the support team a file holding that customer's live session, all to get at four facts. Those are the same four that the evidence section of a good bug report asks for.

They're also why we capture the last 50 network requests in Rebase rather than asking for HARs. Sensitive headers are removed and request text is swept for tokens before anything leaves the page, so support gets the failing request and nobody has to export a thing. Whatever tool you use, the principle holds: collect the failure, not the session.

Found this useful? Pass it on to your team.