One outlet failed five days running, with a different reason each day. The cause was one thing.
The VentureBeat feed died four days with a 429, then on the fifth with an SSL timeout. Different symptoms, one cause: the whole site had gone behind a bot challenge, a JavaScript wall a feed parser cannot pass. Chasing the symptoms would have sent me the wrong way.
This is not a news summary. It is a record of something that happened while building this site.
From September 4 the VentureBeat feed stopped coming in. But the reason it failed changed from day to day. For several days the server returned a 429; on the last day the connection would not even open.
A different error each day
| Date | The reason the archive recorded |
|---|---|
| Sep 4-7 | HTTP 429 (too many requests) |
| Sep 8 | SSL handshake timeout (the connection won't open) |
A 429 says “you are asking too often.” An SSL timeout says “the connection will not even open.” On the surface they are unrelated. One makes you wonder if we called too fast; the other looks like a network problem. One tempts you to lower a rate; the other, to add a retry.
The cause was one thing
Locally, with a clean IP and a real Chrome user agent, the very first request came back 429 with X-Vercel-Mitigated: challenge. The homepage, the /feed/, the old category feeds, all of them. The whole site had moved behind Vercel Attack Challenge Mode, a JavaScript bot challenge.
Because it is a JavaScript challenge, feedparser cannot pass it no matter what you change: user agent, retries, headers. Whether it came back as a 429 or an SSL timeout was only a difference in how the challenge chose to answer. The wall was the same.
How I chose a replacement
I had to switch outlets. Rather than drop in just anything, I checked with the actual parser. The pick was SiliconANGLE AI (category/ai/feed): its server is nginx, so there is no challenge header; it runs a high density of hard AI news (labs, funding, technology); and it publishes daily. The parser confirmed a 200, 30 items, and sane timezones.
Some candidates fell out. ZDNet returned a 404, and Microsoft AI returned a 410 with a Cloudflare check in front of it.
What I am taking from it
Read a multi-day failure one error code at a time and each day looks like its own event. Read them together and it is one. That is why this repo keeps the reason a feed failed in the archive, not just the name. With the reasons kept, the four days of 429 and the fifth day's timeout joined into a single line.
A status code tells you what was blocked, not who blocked it or why. Another note here, on a GitHub 403, says the same. The answer this time was not in the status code either; it was in one header, X-Vercel-Mitigated.