GPS spoofing teleported me to Peru, mid-flight
It seemed like just another typical weekend day, paragliding at Igniș. However, shortly after taking off, things started to get weird.
First, my Android phone suddenly thought it was in Lima, Peru (important for later).

Due to the timezone change, that also triggered a cascade of events: new timezone notification, do-not-disturb mode activated, sunset filter turned on, and so on. The data connection was also interrupted.
As with anything that stops working, I first started with the basic restart dance. First the app(s), then airplane mode, then restarting the phone itself.
While I was attending to the phone, my variometer told me I landed. I questioned reality for a bit but then concluded, no, I am still in the air, flying.
Now, debugging stuff while flying is never ideal, but this time it was even worse because nothing made any sense. Why would two independent devices malfunction at the same time?
It also didn’t help that the weather was starting to build. The clouds were getting taller and rain showers started, just what you want when you’re poking at a phone with a stylus.

It’s not just me
At this point I’ve noticed my flying buddies are also flying kind of erratically. Then I asked on the radio if anyone else is having issues. They were. Now it’s starting to make sense. A handful of devices don’t just randomly fail at the same time.
Then I realized it must be some sort of GPS interference. But what kind of interference? I’ve never seen anything like this before.
After about fifteen minutes of flying with just the basics, my variometer started to recover. My phone’s data connection was restored, but it still said it was in Peru. I’ve tried a few more restart dances, but nothing helped. The weather was deteriorating, and it was no longer safe to multitask, so I called it quits and landed.
Down the rabbit hole
The next day I started going down the rabbit hole trying to understand what happened. That led me to Veritasium’s video on GPS jamming. It’s a really well-made video that explains GPS GNSS in a pretty accessible way. I’ve also learned that the whole coordinate frame is ultimately pinned to stars quasars as a fixed reference, so in a sense we’re still navigating by the stars. Cool.
I then remembered someone actually built a tool that shows these GPS interferences:

So the interference was real. Back on the ground I’d also checked with our local control tower, and they’d had the same thing from their side: aircraft passing through the area reporting bad GPS. Which is more or less how GPSJAM works in the first place, the red hexes are stitched together from passing planes reporting how much they trust their own GPS.
But “interference” turned out to be two different things.
Jamming is blunt: drown out the satellite signals with noise so nothing can get a fix at all.
Spoofing is surgical: broadcast a fake signal that’s stronger than the real satellites, and the receiver happily computes whatever position you feed it. Which is how I ended up in Peru.
Lima
Luck would have it that I caught this conversation in the YouTube comments of the Veritasium video:

Lima is a Ukrainian electronic-warfare system that defends against drones and missiles by convincing them they’re circling overhead in, you guessed it, Lima, Peru.
Which fits, since Igniș is in Maramureș, in the far north of Romania, sharing a border with Ukraine.
So my phone had been reporting the position a missile-defense system wanted an incoming missile to believe.

The failure modes
It’s quite interesting how differently each device handled the same bad data.
There were four of us flying, each with a phone and a variometer, and every one of them got fed the same spoof. I got usable logs from three devices, and no two told the same story.
My Android phone took the spoof and ran with it. It jumped to Lima, recording itself doing circuits over the city. Worse, the bad fix got baked into the cached assistance data (the almanac and the predicted satellite data phones download to speed up the next lock), so even after I landed it still thought it was in Peru. Restarting did nothing. It only recovered once I opened GPSTest and wiped the cached almanac/PSDS to force a cold start.
My variometer runs Linux and keeps a log. The instant the GPS went bad it flipped an internal GpsFixIsValid flag to false, it stopped trusting its own position, and a few minutes later the landing-detector gave up and stopped recording (trimmed, comments mine):
12:18:38 StartRecording: 2026-06-21-Emil-Burzo-01 # took off
12:18:38 Flag 'InFlight' set to active
12:19:22 Flag 'GpsFixIsValid' set to inactive # 44 seconds later, GPS goes bad
12:19:22 Flag 'GpsFixIsValid' set to active
12:19:25 Flag 'GpsFixIsValid' set to inactive
12:29:59 StopRecording # vario decides I've landed
12:29:59 Flag 'InFlight' set to inactive
12:30:16 Warning: postponing recording start until we have a 3D fix
12:34:48 StartRecording: 2026-06-21-Emil-Burzo-02 # GPS back, ~15 minutes later
Across every other flight in that log, going back months, GpsFixIsValid never once flips to inactive. This is the only time it happened.
The flight it saved before “landing” isn’t empty, and it isn’t in Romania. Decoding the raw IGC track:
B 091922 4743666N 02340376E V 01164 00000 # 12:19:22, still over launch, fix now VOID
B 040124 1202321S 07703499W A 01172 00922 # clock and position rewritten...
B 001222 1202321S 07703499W V 01233 00000 # last fix: 12°02'S 077°03'W — Lima, Peru
The variometer’s GPS chip swallowed the spoof just like my phone did. It teleported to Lima, and even had its clock set to nearly midnight, the timestamps jump from 09:19 to 04:01 to 00:12. Out of 702 fixes in that file, 608 are sitting in Peru.
The difference is the single character before the altitudes: V, for void. The firmware wrote down where it was told it was but flagged almost every one of those fixes as not to be trusted, zeroed the GPS altitude, and quietly kept logging the real barometric altitude from the pressure sensor.

The third log was from another pilot, with an iPhone running SeeYou, and the whole time he’d sworn his phone didn’t do anything weird. I’d quietly doubted him. Then he sent the actual iPhone track, and he was right.
It recorded the entire flight, takeoff to landing, one fix per second. Every fix is in Romania. Out of 5,010 of them, zero sit in the southern hemisphere, 4,987 are flagged valid. While my phone did circuits over Lima, this one just kept flying, in the right country, the whole time. Here it is at the exact second everything else broke:
B 091922 4743692N 02340306E A 01177 01303 # 12:19:22, an ordinary valid fix over launch
That’s the timestamp that tripped my variometer’s GpsFixIsValid flag. The worst this one ever did was mark the occasional one-second dropout as void, and even then it held its last real position instead of inventing a new one.
My first instinct was that the iPhone just had a better GPS chip. It doesn’t: a Pixel 9 and an iPhone 17 carry the same class of dual-frequency, multi-constellation receiver. Because I’d also been recording that flight on the same app on my Pixel, that left the operating system underneath as the only real variable between us. Or perhaps some lower level firmware?
The two logs could not disagree more, visible in a single line of the header, where SeeYou records the phone’s timezone:
HFTZNTIMEZONE:-5.0 # my Pixel, mid-teleport: Lima time
HFTZNTIMEZONE:3.0 # the iPhone, the whole flight: Romania time
Same app, same sky, same minute. iOS treated that as invalid. Android wrote Lima straight into the position and the timezone. So it was probably the operating system deciding whether to trust the satellites over everything else the phone already knew?
If you have any idea about where this difference might be coming from, I’d love to know!