Seven forecast-data failures that passed parsing
Seven times, a forecast payload arrived looking like success: HTTP 200, decoded cleanly as GRIB or GeoTIFF, values a chart could draw. Seven times it was wrong anyway — about the place, the direction, the time interval, the model, or the run state. Parsing proved each payload was readable; it took an independent witness to prove what it actually represented.
Every incident below has the same anatomy: what arrived looking fine, the witness that disagreed, and the rule the platform keeps. The atlas pairs them; the cases follow.
Seven forecast-data failures and their independent checks
A payload can parse cleanly while still representing the wrong place, vector, time window, model, or run.
Seven observed provider-data failures, each paired with the independent check that exposed it.
- 01Misregistered WCS cropCompare crop samples with an independent point query.
- 02Successful zero-filled subsetTest physical plausibility: afternoon heat cannot be zero everywhere.
- 03Grid-relative wind left unrotatedRead projection metadata; rotate vectors; compare bearings.
- 04Wrong or truncated model objectVerify Content-Length, ETag, and grid geometry.
- 05Flux window treated as instantaneousInspect GRIB time-range metadata and sequences across resets.
- 06Partially published model runRequest the final required forecast hour before building.
- 07Stale provider identifierQuery live capabilities or the provider directory.
A WCS crop sampled the wrong cells
Arrived
A correctly shaped terrain crop at the requested “native” resolution. The sampled RDPS elevation — 1,426 geopotential metres — was a perfectly plausible number for a mountain site.
Witness
GeoMet's point query reported 1,168 gpm for the same model cell, and 2 m temperatures differed by up to 2.5 °C at half the test sites. A finely oversampled crop reproduced the point values — the fault was the crop's sampling, not the model.
While the pipeline read WCS, the builders compared several crop values with an independent point query before trusting the georeferencing. The transport is retired; the rule is not.
Rule
A crop is a rendered coverage, not proof of nearest-cell sampling.
A broken WCS request returned valid zeros
Arrived
DescribeCoverage advertised `long` and `lat` axes. Subsetting with those names returned HTTP 200 and a valid GeoTIFF — filled entirely with zeros.
Witness
Zero sensible heat flux on a sunny afternoon implies no convection across the entire crop. That is not weather; it is a broken request. The shape actually required the undocumented `x`/`y` axes and an explicit `SUBSETTINGCRS=EPSG:4326`.
As true of a decoded GRIB field as of a rendered crop — and the same distinction the contract keeps on the wire:
Zero is a value; absence is a capability statement
A decoder must preserve the difference between a supported field that reports zero and a field the source does not publish.
Missing capability is not measured zero. This Meteogram shows one atmospheric profile in Etc/UTC. An unsupported gust field is absent, while supported precipitation is present and explicitly zero. All 6 hours explicitly publish precipitationMmHr as zero. No hour carries windGustMps, and the scenario capability declares gust false.
Field present
precipitationMmHr: 0
Interpretation: the source supports this quantity and reports none.
Field absent
windGustMps is not in the document
Interpretation: the source does not publish gust, so its value is unknown.
Rule
Check physical plausibility wherever zero can mean either a measurement or a broken request.
Grid-relative winds were not rotated
Arrived
U and V components decoded normally and produced realistic wind speeds.
Witness
Speed is exactly the property rotation preserves, so a believable magnitude vouches for nothing about direction. In one REPS verification, the unrotated member read 261° where the transformed value was 236.6° — bracketed by deterministic forecasts at 250° and 238°. HRRR errors at these longitudes ran 10–15°.
HRRR’s Lambert grid and REPS’s rotated latitude–longitude grid define their components along grid axes rather than true east and north. The rotation was checked three ways — ecCodes geolocation to about 10⁻⁶ degrees, member-for-member speed against GeoMet, and directional comparison with sibling models — and the builders now read each grid’s vector convention from GRIB projection metadata before deriving direction.
A plausible speed can still point the wrong way
Vector components become meteorological direction only after their grid convention and projection are resolved.
Four-stage validation chain: decode plausible U and V components; read the grid-relative convention from projection metadata; rotate into true east and north; compare the resulting bearing with independent geolocation and sibling-model witnesses. In the recorded REPS check, 261 degrees grid-relative became 236.6 degrees true.
- 01
Parsed payload
U and V decode
The component magnitudes produce a realistic wind speed.
- 02
Projection metadata
Grid axes ≠ true axes
Lambert and rotated-latitude grids declare the component convention.
- 03
Required transform
Rotate before direction
Resolve the vector into true east and north, then derive bearing.
- 04
Independent witness
261° → 236.6°
ecCodes geolocation and sibling forecasts bracket the corrected REPS direction.
What the second witness changes: A correct wind magnitude is compatible with an incorrect bearing because rotation changes direction without changing speed.
Rule
A correct magnitude does not prove a correct direction.
A model URL returned another model’s grid
Arrived
A GEPS orography URL returned 4.3 MB of decodable GRIB.
Witness
The grid inside was REPS-shaped. The one external tell: the body length disagreed with the server's declared Content-Length and ETag. An immediate retry returned the expected bytes; the upstream cause remains unknown.
The download client now checks every full response against its declared length and retries mismatches.
Rule
A valid file format cannot identify the model inside it.
Flux fields used different time intervals
Arrived
Several models expose sensible heat flux in units reducible to W/m² — the same variable, the same unit, believable values everywhere.
Witness
The shared unit hides three different clocks. HRRR and REPS publish instantaneous values; GFS publishes averages over growing windows that reset every six hours; GEPS publishes accumulations that require differencing. Treat all three as instantaneous and afternoon heating smears into the morning.
The builders read product-definition and time-range metadata, then test sequences across window resets.
One unit can describe three different clocks
A field name and W/m² unit do not say whether a heat-flux value is instantaneous, averaged, or accumulated.
A comparison of heat-flux semantics observed in provider products: HRRR and REPS publish instantaneous values; GFS publishes averages over growing windows that reset every six hours; GEPS publishes accumulations that require differencing. Product-definition and time-range metadata, checked as a sequence across resets, identify the semantics.
- 01
HRRR · REPS
Instantaneous
The value describes the product's stated instant.
- 02
GFS
Growing average
The averaging window grows, then resets every six hours.
- 03
GEPS
Accumulation
Successive products must be differenced over their declared intervals.
- 04
Independent witness
Inspect the sequence
Read product-definition and time-range metadata across a window reset.
What the second witness changes: Normalizing units without normalizing the provider's clock can move afternoon heating into the morning while leaving believable numbers.
Rule
A variable name and unit do not define its time semantics.
A model run was only partly published
Arrived
Early forecast hours for a new cycle downloaded cleanly while the provider was still publishing later hours.
Witness
The final scheduled hour was absent. A build started then would have failed after thousands of requests.
The forecast engine probes the final required forecast hour first.
Rule
A run does not exist until its last expected product answers.
Provider paths changed before their documentation
Arrived
Documentation, examples, and old forum answers all pointed to layer families such as `GDPS.ETA_*`, `RDPS.ETA_*`, and legacy ensemble directory trees.
Witness
The live capabilities and directory listings had moved on: some names returned 404; others survived as aliases with different availability.
The forecast model feed reference records what was live-verified and when.
Rule
Provider identifiers are dated observations; the service outranks its prose.
What parsing can never prove
Schema validation proves shape. Each trust boundary also compares the payload with an independent fact about identity, location, projection, or time semantics — and the check lives beside the code that crosses the boundary.
The provider’s relevant vector warning is explicit in the ECCC RDPS data specification: U and V must be resolved relative to the defined grid. The incident-specific countermeasures live in the builders and shared download clients.