← all writing

Gmail let me in, then hung up the phone

I wanted a little program that reads my inbox over IMAP, the old protocol email clients have used forever, so I could do some automation on top of it. Go has libraries for this. I grabbed the newest one, wired it up, pointed it at Gmail, and got this:

imap: select: unexpected EOF

EOF means "the connection closed when I wasn't expecting it to." The other end hung up mid-sentence. The frustrating part was where it hung up. My program connected to Gmail, sent my username and password, and the login succeeded. No error. Then the very next thing it does is ask the server to open the inbox, and on that command the connection just dropped.

That sequence, login works and then the next step fails, is what sent me down the wrong road for a while, because it points your suspicion at everything except the thing that's actually wrong.

#Chasing the wrong suspects

When the login works but the next command dies, your brain says "the credentials are fine, so it's something about my account or Gmail's side." So I went and checked all the Gmail-side things. Is IMAP turned on in the settings? It was. Did Google send me one of those "we blocked a suspicious sign-in" emails I needed to approve? It hadn't. Was it some rate limit, some first-connection-from-a-new-place protection? I poked at all of it.

I also did the boring, important check: from the same machine, could I reach Gmail's IMAP server at all? Open a raw secure connection to it and see if it answers. It did, instantly. So the network's fine, the server's there, my password's accepted. Everything works except the one command I actually need, and it fails the same way every single time. Not flaky. Consistent. Consistent is a clue, because consistent means it's not the weather, it's the wiring.

#The thing I didn't want to suspect

Here's the suspect I kept skipping over, because admitting it meant rework: the library. I'd grabbed the newest version, and "newest" turned out to mean a beta. Pre-release. Not finished.

The reason I kept skipping it is that the login worked. Surely if the library were broken against Gmail, login would fail too. But that logic is wrong, and it's worth saying why. Logging in is a simple exchange. Opening a mailbox involves the server sending back a bunch of chattier status information, and a half-finished client can mishandle that reply, get confused, and have the connection collapse under it. The simple command succeeding tells you nothing about whether the complicated one will. A beta library can absolutely pass the easy test and fall over on the real one.

So I did the unglamorous thing. I ripped the beta library out and dropped in the previous version. The old one. The boring, stable, been-around-for-years one that thousands of people have pointed at Gmail without incident. Rebuilt. Ran it.

440 scanned, 26 relevant

It connected, opened the inbox, read four hundred and forty messages, and went on with its day. The bug was never my account, never Gmail, never the network. It was that I reached for the newest thing on the shelf and the newest thing wasn't done yet.

#The lesson, which I keep relearning

Newer is not better. Newer is newer. There's a reflex, especially with open-source libraries, to grab the highest version number on offer, like it's a fresher loaf of bread. But a "v2 beta" sitting next to a "v1" that's been stable for years is not an upgrade, it's a coin flip. The v1 is boring because it works. The boring one had every behavior I needed and none of the surprises.

There's a tell in this story for the next time, too. When a tool fails in a way that makes you suspect everything but the tool, that's worth noticing. I spent real time auditing my Gmail settings and my network because the failure was shaped like an account problem. But the failure being well-disguised is not evidence about its cause. The connection dropping at a polite, server-driven moment was, in hindsight, a fingerprint of a client that couldn't keep up. I just didn't want to read it, because reading it meant going back and picking a different library, and nobody likes admitting the foundation was the problem.

Swapping it took ten minutes. Suspecting it took an hour, because I didn't want it to be true. That ratio is the whole post.


← all writing