Case

When not crashing isn't enough

or: what a buggy LoL client taught me about product

A system can be technically up. No crash, no error, no alert. And still have completely failed the people who matter. Right technical decision + invisible experience = broken product.

· 4 min

The other day I got definitive proof that the LoL client is still in beta lol

I opened the game. Half of it loaded. The other half simply… didn’t show up for work.

No error. No warning. Nothing.

If you play LoL, you know this isn’t news. The community mantra is old: “the client is garbage”, “feels like it’s in beta”, “over 15 years and they still can’t fix it”. And look at the scale of this: the most played MOBA in the world, with years of revenue to invest, still generates this perception among its players.

Investigation

The client opened, I appeared online. But my name had vanished. Empty friends list, and I have a bunch of people on there who are always connected. There was even that little alert button in the corner, you know? The one that lights up when there’s a server issue.

Blue. All clear. No visible error.

I went to Riot’s status page. Operational. Opened Twitch: a ton of people playing, including on the BR server. Logged into Riot’s website just fine.

But the client was still dead.

That’s when I took off the gamer skin and put on the dev badge.

I went into the logs. There was an ERROR in caps staring right at me. I threw it into ChatGPT: it identified an SSL issue and gave me a link to access directly in the browser. Certificate error.

Nothing unusual so far. But who was issuing this certificate?

It wasn’t Riot.

It was Cisco Umbrella. Which raised the hypothesis of network interception. I switched to 4G tethered from my phone: worked immediately. Back to Wi-Fi: broke again.

Changed DNS to 1.1.1.1. Client came back. Fully functional. As if nothing had happened.

And it was precisely that “as if nothing had happened” that stuck in my head.

The discovery and what it reveals

Riot knows.

There’s no way they don’t. If the client rejects a connection with a certificate from an unknown issuer (and rejects it correctly, mind you) it means it checks. It means at some point someone implemented that validation consciously.

So the client knew something was wrong.

It just didn’t tell me. It left me there, staring blankly at the screen, as if it were my job to understand what can or can’t happen within a context they defined for the client to work in.

From a security standpoint? Absolutely the right call. Not accepting a certificate from an unknown issuer is exactly what prevents man-in-the-middle attacks. The engineering team did their homework.

Engineering made a technically correct decision. Product wasn’t in the room when that decision was made.

Because if they had been, someone would have asked: ok, we reject the connection. But what does the user see?

Nothing.

And “nothing” is not an acceptable answer. It’s a product decision that nobody owned up to making.

Working but broken

A system can be technically up. No crash, no error, no alert. And still have completely stopped working for the people who matter.

For the user, it doesn’t matter that the app didn’t crash. It doesn’t matter that it stayed open in working but broken mode. They couldn’t play. End of story.

I lived the opposite of this on a product I worked on. When we designed the menu sync process between devices, we started getting complaints about slowness: the app was stuck on “Updating Menu”. The process took no more than 25 seconds for an average menu. Technically, it was working.

But the user didn’t know that.

The solution wasn’t to optimize the time. It was to add specific messages about each step of the sync process.

The complaints stopped. Same speed. Completely different experience.

The LoL client knew something was wrong. It chose not to tell me.

That’s not an engineering bug. That’s a product absence.

Right technical decision + invisible experience = broken product. No matter how many catches the engineering team implemented.