kimo
GuideAdvanced11 minDefense

Detect GNSS interference from aircraft data

You can detect likely GNSS interference from aircraft data by watching the navigation-quality fields aircraft broadcast in ADS-B: when many aircraft that normally report good accuracy (NACp) and integrity (NIC) suddenly report degraded values in the same area and time window, satellite navigation there was probably disrupted. This guide shows how to flag degraded aircraft robustly, aggregate them into hexagonal cells, apply minimum-sample and coverage gates, choose thresholds, and present the result honestly as an indicator of degraded navigation, not as proof or attribution.

Hugo Lefèvre · Aviation data analyst
11 min read

At a glance

Level
Advanced
Time
11 min

Prerequisites

  • A state_vectors model with NIC and/or NACp per position (see the ADS-B ingestion guide)
  • A coverage_cells model so empty cells can be shown as unknown
  • DuckDB, Postgres or ClickHouse with an H3 extension, or Kimo’s built-in hex binning
  • Agreement within your team on purpose, retention and reporting channel

You will end up with

A daily and hourly interference-indicator layer (nav_quality_cells) with documented thresholds, gating and caveats, rendered in the Airspace map and usable by alert rules.

§01Why does aircraft data reveal GNSS interference?

Most aircraft compute their ADS-B position from GNSS and broadcast, alongside it, how confident they are. Two fields carry that confidence. NACp (Navigation Accuracy Category for position) bounds the 95% horizontal position error; NACp 8 means better than 0.05 NM (93 m) and NACp 0 means worse than 10 NM or unknown6. NIC (Navigation Integrity Category) gives a containment radius within which the true position should lie; NIC 7 corresponds to under 0.2 NM (370 m)6. US rules require compliant ADS-B Out installations to report NACp better than 0.05 NM and NIC better than 0.2 NM, and to broadcast NIC changes within 12 seconds and NACp changes within 10 seconds5. In other words, under normal conditions a modern airliner reports NACp ≥ 8 and NIC ≥ 7, and when its GNSS degrades, it says so quickly.

Researchers have used this repeatedly. Studies of OpenSky data show NACp falling from values above 8 to 0 when aircraft are affected by radio-frequency interference, and recovering once they leave the affected area2. NIC is carried in every airborne position message (every 0.4–0.6 s), while NACp travels in the less frequent operational-status message (every 2.4–2.6 s), which is why some work prefers NIC as a per-position proxy for GNSS reception quality3. Public maps such as GPSJAM aggregate the same kind of signal daily into hexagons4. The relevance is not academic: EASA reports increasing jamming and spoofing since February 2022, especially around conflict zones, and asks air navigation service providers to collect and communicate information on GNSS degradation1.

Mapping GNSS interference from ADS-B quality fieldsMethod overview: per-aircraft degradation flags (NIC/NACp) are aggregated into hexagonal cells per window, gated by sample size and coverage, then classified into indicator bands for the daily map.Position reports (simulated)AircraftNICNACpNavSIM101810okSIM20279okSIM30300lowSIM404810okSIM50524lowSIM60679okFlag degradedNIC or NACp below thresholdAggregate to hexes% degraded per cell per dayLow< 2% aircraftMedium2–10%High> 10%Illustrative grid · simulated data
Figure.Method overview: per-aircraft degradation flags (NIC/NACp) are aggregated into hexagonal cells per window, gated by sample size and coverage, then classified into indicator bands for the daily map.

Scroll sideways to see the full diagram.

§02Step 1: make sure you have the right quality fields

Open state-vector APIs often omit NIC and NACp; the OpenSky live state vector does, for example. You need decoded airborne-position and operational-status messages from your own receivers or a historical source. Research using OpenSky merged state vectors with NACp decoded from operational-status messages on the aircraft address and timestamp2; the ingestion guide adds the nic, nacp and nacp_age_s columns for exactly this purpose.

FieldMessageRate (ADS-B v2)Good valueDegraded signal
NICAirborne positionAbout every 0.4–0.6 s≥ 7 (Rc < 0.2 NM)Drops below 7, often to 0
NACpOperational statusAbout every 2.4–2.6 s≥ 8 (EPU < 0.05 NM)Drops to 0 (> 10 NM or unknown)
Quality fields used for interference indication. Values from Sun, The 1090 Megahertz Riddle (uncertainty chapter), 14 CFR 91.227 and Liu et al. 2025.

§03Step 2: decide which aircraft can testify

Some aircraft report NACp 0 all the time, for example because they have no GNSS receiver. Counting them as "degraded" would paint permanent false interference wherever they fly. Figuet and colleagues handled this by labelling a flight as affected only if it reported NACp = 0 for more than 60 seconds cumulatively and NACp above 7 for more than 60 seconds2. The idea generalizes: an aircraft is an eligible witness only if it showed good quality at some point in the same flight.

Eligible aircraft and per-position degradation flags
sql
create or replace view nav_quality_positions as
with per_flight as (
  select
    f.flight_id,
    sum(case when s.nacp >= 8 or s.nic >= 7 then 1 else 0 end) as good_positions
  from flights f
  join state_vectors_clean s
    on s.icao24 = f.icao24
   and s.obs_time between f.first_seen and f.last_seen
  group by f.flight_id
)
select
  s.*,
  f.flight_id,
  (pf.good_positions >= 60)                           as eligible,   -- ~30 s of good NIC at 2 Hz
  (s.nic is not null and s.nic < 7)
    or (s.nacp = 0 and coalesce(s.nacp_age_s, 99) <= 10) as degraded
from state_vectors_clean s
join flights f
  on s.icao24 = f.icao24
 and s.obs_time between f.first_seen and f.last_seen
join per_flight pf on pf.flight_id = f.flight_id
where not s.on_ground;

Two details in that query matter. The NACp test only trusts values received in the last 10 seconds (nacp_age_s), because a stale NACp attached to a fresh position can make an aircraft look degraded long after it recovered. And eligibility is computed per flight, not per aircraft, because the same airframe can fly with different equipment states on different days.

§04Step 3: require persistence per aircraft

A single degraded position is usually noise: a decoding issue, a brief antenna masking during a turn, a receiver glitch. Mark an aircraft as affected in a window only if it accumulated enough degraded time there. We default to 60 seconds cumulative, matching the published criterion2; at the nominal 2 Hz position rate that is up to about 120 degraded position messages, fewer where reception is patchy, which is why the query below sums time rather than counting messages.

Affected aircraft per cell and hour
sql
create or replace table nav_quality_aircraft as
select
  h3_latlng_to_cell(lat, lon, 4)      as h3_cell,
  date_trunc('hour', obs_time)        as window_start,
  case when baro_alt_m < 3000 then 'low'
       when baro_alt_m < 7500 then 'mid' else 'high' end as alt_band,
  icao24,
  -- approximate degraded seconds from position spacing (capped at 5 s per gap)
  sum(case when degraded then least(coalesce(
        extract(epoch from obs_time - prev_time), 0), 5) else 0 end) as degraded_s,
  bool_or(degraded)                   as any_degraded
from nav_quality_positions
where eligible
group by all;

§05Step 4: aggregate into hexagonal cells

Hexagons are the standard choice because every neighbor is equidistant and cells tile without the distortion of latitude-longitude squares. The resolution is a tradeoff between spatial detail and sample size: each cell needs enough eligible aircraft per window to produce a stable share. Start coarse (H3 resolution 3 or 4 for regional daily maps), check the distribution of aircraft per cell, and only refine where traffic is dense. The 2022 Eastern Europe study similarly presented results in hexagonal bins as a percentage of reports with NACp 0, removing the dependence on traffic volume2.

Formula

Degraded share=max(affected aircraft − 1, 0) ÷ eligible aircraft observed

where
Affected aircraft
Eligible aircraft with at least 60 s of degraded quality in the cell and window
Eligible aircraft observed
Eligible aircraft with at least one position in the cell and window
− 1
Denoising step used by GPSJAM: one degraded aircraft alone never colors a cell

The subtract-one step comes from GPSJAM, which computes 100 * (bad − 1) / (good + bad) per hexagon to reduce false positives in cells with few flights4. It also means that very sparse cells can hide genuine interference, which is one more reason to show sample size next to every value.

nav_quality_cells: share, gating and indicator band
sql
create or replace table nav_quality_cells as
with agg as (
  select
    h3_cell, window_start, alt_band,
    count(*)                                         as eligible_aircraft,
    count(*) filter (where degraded_s >= 60)         as affected_aircraft
  from nav_quality_aircraft
  group by all
)
select
  a.*,
  greatest(a.affected_aircraft - 1, 0)::double
    / nullif(a.eligible_aircraft, 0)                 as degraded_share,
  (a.eligible_aircraft >= 8)                         as sample_ok,
  (c.aircraft is not null)                           as coverage_ok,
  case
    when a.eligible_aircraft < 8 or c.aircraft is null then 'insufficient'
    when greatest(a.affected_aircraft - 1, 0)::double / a.eligible_aircraft > 0.10 then 'high'
    when greatest(a.affected_aircraft - 1, 0)::double / a.eligible_aircraft >= 0.02 then 'elevated'
    else 'normal'
  end                                                as indicator_band
from agg a
left join (
  select h3_cell_to_parent(h3_cell, 4) as h3_cell, hour, alt_band, sum(aircraft) as aircraft
  from coverage_cells group by all
) c
  on c.h3_cell = a.h3_cell and c.hour = a.window_start and c.alt_band = a.alt_band;

§06Step 5: choose thresholds you can defend

There is no universal threshold, and you should resist inventing precision you do not have. A transparent starting point is the band structure GPSJAM publishes for daily maps: under 2% of aircraft reporting low accuracy is shown as normal, 2–10% as elevated, and more than 10% as high4. We use the same bands by default, add a minimum of 8 eligible aircraft per cell and window (a Kimo default, not a published standard), and evaluate hourly and daily windows separately.

ParameterKimo defaultRationaleWhen to change it
Per-aircraft persistence60 s cumulative degradedPublished criterion for affected flights (Figuet et al.)Raise for very dense receiver networks with frequent glitches
Eligibility≥ 30 s good NIC/NACp in same flightExcludes aircraft that never report good qualityLower only if most traffic is short regional hops
Minimum sample8 eligible aircraft per cell-windowAvoids bands driven by one or two aircraftLower with coarser cells; never below 3
Elevated band2–10% degraded shareMatches GPSJAM daily bandsTune per region after a baseline month
High band> 10% degraded shareMatches GPSJAM daily bandsTune per region after a baseline month
Altitude splitLow / mid / high bandsLow-flying aircraft are less affected (Figuet et al.)Collapse if traffic is sparse
Default parameters. Bands from the GPSJAM FAQ; persistence, eligibility and altitude rationale from Figuet et al. 2022; minimum sample is a Kimo engineering default.

Altitude deserves its own dimension. In the 2022 Eastern Europe study, low-flying aircraft tended to be less affected than those at higher altitudes2, which is consistent with line-of-sight radio propagation. A cell that is "high" at cruise altitude and "normal" for low traffic is therefore not contradictory, and splitting by band avoids averaging the effect away.

Cells in each indicator band per day, fictional region
  • Elevated (2–10%)
  • High (>10%)
Figure. Illustrative data: simulated daily counts of H3 cells by indicator band for a fictional region, showing a three-day episode. Not real measurements.

§07How do jamming and spoofing differ in the data?

EASA defines jamming as interference that prevents receivers from locking onto satellite signals and spoofing as counterfeit signals that deceive receivers, and notes symptoms such as position discrepancies, time shifts and spurious terrain warnings1. In ADS-B data the two leave different fingerprints, and the method above is designed for the first.

PatternWhat you typically seeWhat this method does
Quality collapse (consistent with jamming)NIC/NACp fall toward 0; positions may freeze, coarsen or disappearDetected by degraded share
Implausible positions with good quality (consistent with spoofing)High NIC/NACp but positions jump, cluster, or disagree with velocity or MLATNot detected by quality fields; flag via kinematic and multi-source checks
Equipment or decoding issuesOne aircraft or one receiver, no spatial clusteringRemoved by eligibility, persistence and the minus-one step
Interference patterns as they appear in ADS-B data. Definitions from EASA.

Kimo keeps a separate, conservative "position integrity" signal built from the implausible_jump flag in the ingestion model and from disagreement between ADS-B and MLAT positions where available. It never labels a cell as spoofing on its own; it raises a review task for an analyst, who compares with official information.

§08Step 6: validate against official information

An indicator layer earns trust by agreeing with independent information where it exists. EASA maintains, alongside its Safety Information Bulletin (in its fourth revision as of 3 July 2026), a page of affected flight information regions derived from ADS-B data1. The EASA–IATA mitigation plan calls for standardized NOTAM Q-codes for GNSS interference and timely sharing of interference event data7. Join your daily cells to active notices and to the authority's published regions: matches are corroboration; persistent "high" cells without any official mention are candidates for reporting through your proper channel, not for publication.

Before you share an interference map

  • Every colored cell shows its eligible-aircraft count and window.
  • Cells without coverage or below the minimum sample are visibly "insufficient", not green.
  • The map states the thresholds, persistence and eligibility rules used.
  • Altitude bands are shown or the map says they were combined.
  • The caption says the map shows where aircraft reported degraded navigation, not where a source is.
  • Comparisons with official notices or authority pages are noted.
  • Individual aircraft identities are not shown in shared outputs.

§09What are the limitations of this method?

  • Delayed degradation. Aircraft with tightly integrated GNSS and inertial navigation may report reduced quality late, which distorts the apparent area and duration2.
  • Invisible already-degraded flights. A flight that enters your area already at NACp 0 cannot be counted as newly affected2.
  • Coverage holes. Data over water and in some regions is thin or absent, and cells without traffic or receivers stay blank24.
  • Not every red cell is hostile. GPSJAM notes that low accuracy can have other causes, including testing of military systems, and that a short disruption can color a whole day4.
  • Altitude bias. Aircraft at altitude can experience interference that people on the ground do not4.
  • Localization is hard and assumption-heavy. Published source-localization methods assume a single, static, unobstructed source and adequate receiver coverage3. Kimo does not attempt it; leave attribution to authorities.

§10Running it in Kimo

The GNSS interference monitor template packages the models above with simulated data, a daily map, an hourly drill-down by altitude band, and an alert rule that fires when a cell cluster stays "high" for two consecutive hours. Thresholds are declared in YAML so changes are reviewed and logged.

models/nav_quality.yaml (excerpt)
yaml
model: nav_quality_cells
source: nav_quality_cells
time_dimension: window_start
parameters:
  persistence_seconds: 60
  eligibility_good_positions: 60
  min_eligible_aircraft: 8
  bands:
    elevated: 0.02
    high: 0.10
measures:
  degraded_share: { sql: "sum(greatest(affected_aircraft - 1, 0)) / nullif(sum(eligible_aircraft), 0)", format: percent }
  cells_high: { sql: "count(*) filter (where indicator_band = 'high')" }
  cells_insufficient: { sql: "count(*) filter (where indicator_band = 'insufficient')" }
caveats: >
  Indicates where eligible aircraft reported degraded GNSS quality.
  Not evidence of a source location or intent. Coverage-gated.
retention: 400d

Open the result in the Airspace view with the coverage layer on, and see Airspace alerting rules that analysts trust for the alert definition. For the wider context, including privacy and licensing, read the whitepaper Airspace Awareness from Open Data and the shorter blog post on mapping interference.

Sources

7 references
  1. Global Navigation Satellite System outages and alterations (SIB 2022-02R4) (opens in a new tab)
    European Union Aviation Safety Agency (EASA)2026easa.europa.eu

    Jamming vs spoofing definitions and symptoms; increase since February 2022; ANSP recommendations; FIR list derived from ADS-B.

  2. GNSS Jamming and Its Effect on Air Traffic in Eastern Europe (opens in a new tab)
    Figuet, Waltert, Felux, Olive — Engineering Proceedings 28(1), 122022digitalcollection.zhaw.ch

    NACp > 8 to 0 under RFI; 60 s criteria; hexagonal bins; altitude effect; limitations.

  3. Locating GNSS Interference Sources using ADS-B with Non-linear Least Squares (opens in a new tab)
    Liu, Lo, Blanch, Chen, Walter — NAVIGATION 72(3)2025navi.ion.org

    NIC vs NACp message rates; NIC as proxy; localization assumptions.

  4. GPSJAM — Frequently asked questions (opens in a new tab)
    GPSJAM.orggpsjam.org

    Daily hexagon map; 2% and 10% bands; (bad − 1) / (good + bad) formula; caveats.

  5. 14 CFR § 91.227 — ADS-B Out equipment performance requirements (opens in a new tab)
    Cornell Law School Legal Information Institutelaw.cornell.edu

    NACp < 0.05 NM and NIC < 0.2 NM; NIC changes within 12 s, NACp within 10 s.

  6. The 1090 Megahertz Riddle (2nd ed.) — Uncertainty: NIC, NAC and SIL (opens in a new tab)
    Junzi Sun, TU Delft (mode-s.org)mode-s.org

    NIC containment radii and NACp EPU tables; version-dependent NIC derivation.

  7. EASA and IATA publish comprehensive plan to mitigate GNSS interference (opens in a new tab)
    EASA press release2025easa.europa.eu

    Standardized NOTAM Q-codes; sharing of RFI event data.

External sources were accessed at the time of writing. Kimo product details, customers and figures in examples are illustrative unless a source is cited.

0%

Mark as done

0 of 10 sections done

Frequently asked questions

Which field is better for detecting interference, NIC or NACp?

Both work. NIC arrives with every airborne position message, so it gives per-position resolution; NACp arrives less often but is the field used in several published studies. Use NIC where you have it, check NACp freshness, and require both to agree when possible.

What threshold means a cell is affected?

There is no universal value. A transparent starting point is the GPSJAM banding: 2–10% of aircraft degraded is elevated, above 10% is high, combined with per-aircraft persistence and a minimum sample size. Tune per region after observing a baseline.

Can this method detect spoofing?

Not reliably. Spoofed receivers can report good quality while positions are wrong. Use kinematic consistency and comparison with independent positions such as MLAT, and route suspected cases to an analyst rather than labelling them automatically.

Can I find where the interference comes from?

Research methods exist but rely on strong assumptions about the source and coverage. Kimo does not attempt localization; report persistent indications through official channels and leave attribution to authorities.

Why do some red cells appear far from any conflict?

Degraded quality has several causes, including authorized testing and equipment issues, and aircraft at altitude can see interference from far away. Check sample size, altitude band and official notices before drawing conclusions.

Put it to work

Skip the setup — start from a working version.

GNSS interference monitor: Daily interference map from aircraft navigation-accuracy reports.

All resources
Whitepaper
Defense

Airspace Awareness from Open Data

ADS-B, Mode-S and GNSS interference: what open aviation data can reveal, its limits, and how to fuse it responsibly.

Hugo Lefèvre
32 pages
Template
Defense

GNSS interference monitor

Daily interference map from aircraft navigation-accuracy reports.

Kimo team
4 min setup

Airspace awareness from open data.

Fuse ADS-B, AIS and OSINT feeds on your own infrastructure. The demo runs entirely on simulated data.