For about a week, returning users who opened our portal watched the word "Loading…" sit on the screen for ten seconds before the login page appeared. Not sometimes. Not roughly. Ten seconds, every time, and then everything worked perfectly. First-time visitors never saw it. Only people who had signed in before.

A bug that takes a random amount of time is a performance problem. A bug that takes exactly ten seconds is a confession. Nothing in a healthy web request rounds itself off to a clean power of ten. That number is not the sum of some real work; it is the ceiling of a timeout, and a timeout means something, somewhere, is patiently waiting for a thing that is never going to arrive.

This is the story of what it was waiting for, and why the thing it waited for was blocked by a security header we were proud of.

What the portal does on mount

Our portal is a single-page app. When it loads, before it shows you anything, it tries to answer one question: are you already signed in? The polite way to do that with OIDC is a silent check. The app asks the identity provider "if this browser already has a session, hand me a fresh token without bothering the user." Our client library, oidc-client-ts, exposes this as signinSilent(), and we called it on mount from a renewSession() helper.