Send a User-Agent so adsb.lol stops returning 403 - #18
Merged
Conversation
adsb.lol refuses requests whose User-Agent is missing or too generic:
HTTP 403 "User-Agent too generic; include valid contact info."
Node's https.get sends no User-Agent at all unless one is set, which puts us
in the most-blocked category possible. Every fallback request has been failing,
on every node, since adsb.lol introduced the rule - nothing changed on our
side, and there is no deploy to correlate it with.
Verified A/B against the live API, same URL and same second:
no User-Agent -> 403
curl/7.88.1 -> 200
retina-node/1.0 (+github url) -> 200, 45 aircraft
The rule is a blocklist of generic tokens rather than a real contact-info
check - Mozilla/5.0 passes - but a descriptive agent is what they are asking
for and is least likely to be caught when they tighten it. ADSBLOL_USER_AGENT
overrides it, which is the hook for a real contact address; the default points
at the repo because inventing an ops mailbox would be worse than useless.
Also read the body of a non-200 instead of discarding it. The reason was
sitting in a 52-byte response the whole time, and throwing it away is why this
presented as "no aircraft nearby" rather than "we are being refused" - on nodes
whose local receiver was also dead, it looked exactly like a quiet sky. That is
what let it run undetected.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 24, 2026
|
Reviewed the diff ( Code quality
Potential bugs
Performance
Security
Test coverage
Overall: solid, targeted fix for a real bug, backed by good live verification. Nothing blocking. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
18 insertions, 2 deletions. Urgent — this is a live fleet-wide outage.
The bug
Node's
https.getsends noUser-Agentat all unless one is set, which puts us in the most-blocked category possible. Every adsb.lol fallback request has been failing on every node since adsb.lol introduced the rule. Nothing changed on our side and there's no deploy to correlate it with, which is why it went unnoticed.Combined with the dead
adsb_sourcedefault (fixed in retina-node#32), nodes have had no ADS-B ground truth from either source.Verified A/B against the live API, same URL and same second
curl/7.88.1Mozilla/5.0retina-node/1.0 (+github url)The rule is a blocklist of generic tokens rather than a real contact-info check —
Mozilla/5.0passes — but a descriptive agent is what they're asking for and least likely to be caught when they tighten it.ADSBLOL_USER_AGENToverrides it, which is the hook for a real contact address; the default points at the repo rather than inventing an ops mailbox.Also: read the body of a non-200
The reason was sitting in a 52-byte response the whole time and the code discarded it. That's why a hard 403 surfaced as "0 aircraft" — on nodes whose local receiver was also dead, indistinguishable from a quiet sky. That's the part that let this run undetected, so it's worth fixing alongside the header.
Deployed and confirmed on hardware
Hot-patched onto jonathan-node-1 via
docker cp(backup at/opt/proxy/server.js.bak-preUA):X-Data-Sourcelocaladsb.lolPositions sanity-checked against the node's configured location: 43/43 within the 120 nm radius, nearest 52 km, farthest 213 km — genuine local traffic, not another region's feed.
Note
Was previously bundled with the response-cache rewrite in #17. Split out so this can be reviewed and merged on its own. The cache work is now #19 — it touches the same
fetchUrl, so whichever lands second needs a rebase.🤖 Generated with Claude Code