ITSFeed

The data, standards, and technology behind mobility.

ITS
Intelligent transportation systems
Feed
The live data layer

Explainer · Quality & Compliance

What the GTFS validator actually checks, and why feeds still fail

MobilityData's canonical validator has 181 notice codes, three severities, and one word that matters for compliance. We ran 736 live US feeds through it and read four years of California's monthly reports to see what actually fails.

The City of Madera publishes a GTFS feed that fails validation. It fails because the phone number in agency.txt reads “(559) 661-RIDE (7433)”, and the validator, told the feed is American, cannot parse RIDE as digits. That is the only error in the feed. Another 28 US feeds fail because they contain a file called rider_categories.txt that the Metropolitan Transportation Commission defined for the Bay Area in 2011 and that GTFS adopted, with different columns, in 2025. And 11 feeds fail because a vehicle is scheduled to be in two places at once.

None of that is what an agency imagines when it hears its feed “has errors.” The canonical GTFS Schedule validator is a conformance checker, and conformance is a moving target: the rulebook has grown release by release to 181 codes, and rules have changed severity on the way. To see what a failure means, we ran every live US feed in the Mobility Database catalog through the current release and then read four years of California’s monthly quality reports, where the same check has been run against the same agencies every month since July 2022.

What the validator is

MobilityData’s validator is a Java program, open source under Apache 2.0, that loads a GTFS zip from disk or a URL, checks that each file parses, and then runs a few hundred rules against the tables. It writes three things: a report.json with every notice, a report.html of the same for humans, and a system_errors.json that is empty unless the validator itself broke. The release page shows the pace: v1.0.0 on 2020-03-11, v4.0.0 on 2022-10-25, v5.0.0 on 2024-03-15, v7.0.0 on 2025-03-10, and v8.0.1, the current release, on 2026-05-12. Google’s older Python validator, transitfeed, is archived and last changed in September 2022.

There are four ways to run it. The web version at gtfs-validator.mobilitydata.org takes a zip or a URL and returns a report link that works for 30 days. There are desktop installers for Windows, macOS and Linux. The command line is a single jar that needs a Java 17 runtime, and there is a Docker image that wraps it. All four produce the same report, and the jar exits with status 0 whether the feed is clean or full of errors. We checked on a feed with five distinct error codes: the process reported success, because from the validator’s point of view it had succeeded in producing a report.

That matters because “the validator passes” is a decision someone downstream has to make by reading the report. Nothing in the tool blocks a bad feed. Google Maps, for its part, runs a separate list of checks when it imports a feed through the Transit Partner Dashboard; its documentation lists 40 blocking errors and 81 warnings of its own, with names like “Agencies With Different Timezones” that do not map one to one onto the canonical codes.

Three severities, and only one counts

Every notice carries a severity, and the rules page defines the three in terms of the spec’s own language. An ERROR corresponds to a violation of the GTFS Schedule Reference, “items explicitly required or prohibited,” the places where the reference says “must.” A WARNING corresponds to a best practice, where the reference says “should” or the separate best-practices document recommends something. An INFO notice “highlights items that may affect the overall quality of the feed,” which in practice means a file or column the spec does not define.

The rules.json shipped with v8.0.1 lists 181 notice codes, of which five describe the validator’s own failures rather than the feed’s (an I/O error, a thread that died, a URL that would not parse), which leaves 176 that describe the data.

Severity Codes in v8.0.1 What it means Example
ERROR 111, of which 5 are validator failures The feed violates something the reference requires or prohibits missing_required_column, foreign_key_violation, block_trips_with_overlapping_stop_times
WARNING 53 The feed departs from a best practice stop_without_stop_time, feed_expiration_date7_days, fast_travel_between_consecutive_stops
INFO 17 Something worth a look that is not wrong unknown_file, unknown_column, big_gap_in_service

Only the first row is used as a pass or fail line anywhere we could find. California’s Transit Data Guidelines define a compliant schedule feed as one that “regularly passes the canonical validator with no errors,” alongside a stable URL, an open license, and acceptance by major trip planners. The same document lists the FTA requirement that NTD reporters “maintain a public domain GTFS dataset” at a public link as an NTD mandate; the no-errors check is marked as a Caltrans check that Cal-ITP monitors. We found no federal rule that a feed pass the validator. Since report year 2023 the National Transit Database has collected the link, and the link is what gets checked.

Warnings, then, are advisory, and a feed can carry hundreds of thousands of them and still be compliant everywhere that word is used, which describes most feeds.

What 736 live US feeds actually trip on

The Mobility Database catalog, in the snapshot we took on 2026-08-21, listed 828 US schedule feeds that were not marked deprecated or inactive. On 2026-09-29 we fetched each one from the URL the catalog gives consumers, got a zip back from 736 of them, and ran every zip through the v8.0.1 jar with the country set to US and the validation date pinned to that day. The 92 that did not deliver a zip are their own finding, below. These are feeds, not agencies: one operator can publish several, and the MTA alone publishes nine.

In all, 103 feeds, 14 percent, carried at least one ERROR notice. The other 633 would pass California’s check. Only 21 feeds produced no notices at all, and 47 produced nothing above INFO. The median feed produced 62 notices across 3 distinct warning codes, and 688 of 736 carried at least one warning. Across the 103 failing feeds there were 26 distinct error codes, and 85 of the 103 had exactly one.

Horizontal bar chart of the twelve most common ERROR notice codes across 736 US GTFS feeds validated on 2026-09-29. missing_required_column leads with 30 feeds, highlighted in amber, followed by trip_distance_exceeds_shape_distance at 19, block_trips_with_overlapping_stop_times at 11, decreasing_or_equal_stop_time_distance and equal_shape_distance_diff_coordinates at 9 each, stop_time_timepoint_without_times at 7, invalid_phone_number at 6, and five codes at 3 or 4 feeds.
ERROR notice codes by the number of feeds carrying them. The top bar is one file, rider_categories.txt, in 30 feeds. Source: ITS Feed census of 736 US GTFS feeds from the Mobility Database catalog (snapshot 2026-08-21), fetched and validated 2026-09-29 with the canonical validator v8.0.1.

The single most common error has nothing to do with a schedule. In 30 feeds the validator reports a missing required column in rider_categories.txt, and in 28 of them the file’s header reads rider_category_id,rider_category_description. That header is from MTC’s GTFS+ format specification, the set of extra files the Bay Area’s 511 program has asked its operators for since 2011; the document’s own revision table dates the rider categories file to 2011-03-22. On 2025-02-21 the GTFS community merged a Fares v2 proposal that added an official rider_categories.txt with different columns, including a required rider_category_name and a required is_default_fare_category, and validator v7.0.0 shipped the rules for it 17 days later. Every feed still carrying the regional file under the now-official name fails the new rules’ column check. Trillium is the named publisher of 27 of the 30, and the two with a newer header, Simi Valley and Auburn, fail only on the default-category column. Take that one collision out and 77 feeds carry an error rather than 103.

The next three codes are one bookkeeping problem. trip_distance_exceeds_shape_distance (19 feeds), decreasing_or_equal_stop_time_distance (9) and equal_shape_distance_diff_coordinates (9) all police shape_dist_traveled, the running distance along a shape that stop_times.txt and shapes.txt each carry. The first fires when a trip’s recorded distance runs past the end of its shape and the last stop sits 36 feet or more from the shape’s last point; under 36 feet the same condition is a warning, which 90 feeds carry. North Country Express in New York trips it with distances that differ by 3 millimeters, 165,624.23 against 165,624.227, because the trip’s figure was rounded up and its last stop sits 189 feet past where the drawn shape ends. The other two codes catch distances that fail to increase from one point to the next.

In 11 feeds, trips in the same block have overlapping stop times, meaning the same vehicle is scheduled in two places at once. That is a real scheduling defect, and it is where the large agencies show up: NJ Transit’s bus feed, the Puget Sound consolidated feed, and the MTA’s Manhattan bus feed all carry it. Maryland’s MARC Train feed carries it once, on two trains sharing a block on a single day. Among the 20 largest feeds in the census, six carry an error of some kind, and by file size the share with an error rises from 10 percent of the smallest quarter to 19 percent of the largest.

A phone number is enough to fail six feeds. The validator only checks phone numbers when it is told the country, and with the country set to US it rejects vanity numbers: Madera’s 661-RIDE, Ketchikan’s 225-TRAN, and a bare “+1” on Brightline’s. For all six that is the only error, so a pipeline that runs the validator without the country flag, which is the default, would count 97 failing feeds, not 103.

Warnings are where most feeds live

Passing says nothing about how much the validator found. Here is what the 736 feeds carried above INFO, by the share of feeds rather than the count of notices, because notice counts are dominated by a handful of feeds.

Warning Feeds (share of 736) What it means
stop_without_stop_time 356 (48%) A stop in stops.txt that no trip visits
expired_calendar 294 (40%) A service period in calendar.txt that has already ended
mixed_case_recommended_field 234 (32%) A name written in all capitals or all lower case
trip_coverage_not_active_for_next7_days 178 (24%) No trip runs in the next seven days
feed_expiration_date7_days 148 (20%) feed_info.txt says the feed expires within a week
missing_feed_contact_email_and_url 142 (19%) No way listed to reach the publisher
fast_travel_between_consecutive_stops 128 (17%) A vehicle would exceed a speed threshold between two stops
missing_recommended_field 109 (15%) A field the reference recommends is blank
stop_too_far_from_shape_using_user_distance 96 (13%) A stop sits far from the shape at the distance the feed claims
trip_distance_exceeds_shape_distance_below_threshold 90 (12%) The shape-distance mismatch, under the error line

Notice counts point the other way. Honolulu’s TheBus feed produced 1,538,157 notices, 1,428,712 of them missing_timepoint_value, which fires once for every stop time that carries an arrival or departure but no timepoint value. Lansing’s CATA feed alone produced 633,644 of the same. Only 32 feeds carry that warning, and between them they produced 3.1 million notices, more than every other code combined. Notice counts do not rank feeds: one warning repeated a million times can sit in a feed in better shape than one with 40 different warnings.

The rows that should worry a consumer are the fourth and fifth. In 178 feeds, 24 percent of the ones we could fetch, the validator found no trip scheduled for the seven days after 2026-09-29, and in 123 the feed’s own feed_info.txt end date had already passed, 69 of them by more than a year. Those sets overlap; 190 feeds are in one or the other. The catalog carries a seasonal flag that would explain some of them, ski shuttles and national seashores among them, and it is blank on all 736. The point for the validator is that none of this is an error. A feed that describes service that ended in 2023 passes, with warnings, exactly as it did in 2023.

The INFO tier is mostly extension traffic: 431 feeds carry a column the spec does not define and 357 carry a file it does not define. Some of that is vendor bookkeeping and some of it is the same GTFS+ family that caused the top error, sitting harmlessly under names the spec has not yet reused.

Four years of California, month by month

The Mobility Database census is a snapshot. For a time series we used Cal-ITP’s Monthly GTFS Quality Reports, which since mid-2022 have published a page per California agency per month with a row for each guideline check, including “No errors in MobilityData GTFS Schedule Validator,” sampled on two dates a month. We read all 9,069 agency-month pages, June 2022 through August 2026, and took the first sampled date of each month; the validator check appears from July 2022.

Line chart of the share of California transit agencies passing Cal-ITP's 'no errors in the MobilityData validator' check each month from July 2022 to August 2026. The all-agencies line starts at 68 percent, falls to 33 percent in December 2022, climbs through 2023 and 2024 to the mid-60s, and ends at 67 percent. A second line excluding Bay Area 511 participants runs about 15 points higher and ends at 83 percent.
Share of agencies in each monthly report whose feed produced no validator errors on the first sampled date. The upper line excludes agencies whose schedule feed is the Bay Area 511 regional feed. Source: Cal-ITP Monthly GTFS Quality Reports, reports.dds.dot.ca.gov, 9,069 agency-month pages read 2026-09-29.

In July 2022, 93 of 137 agencies passed. By December 2022 it was 61 of 183. In August 2026 it was 120 of 178. Read as a line about agencies, that is a collapse followed by a slow recovery to roughly where things started. Read against the validator’s release history, much of it is the rulebook moving.

The December 2022 drop is 35 agencies flipping from pass to fail in one month, and their new errors are almost all invalid_currency_amount and missing_required_field in fare files. Validator v4.0.0, released 2022-10-25, introduced invalid_currency_amount as an error, and its own release notes list dozens of Trillium-built California feeds among the examples it caught. Cal-ITP picked up the new release, and a fifth of the state failed a check it had passed the month before. In October 2023, 15 agencies flipped back, 11 of them with that one currency error as their only failure.

The 2024 step has the same shape in reverse. Validator v5.0.0, released 2024-03-15, downgraded stop_without_zone_id from ERROR to INFO and narrowed when it fires. In February 2024, 8 of the 86 failing California agencies had that as their only error. In March, none did. Over the same period five codes changed severity in the tables, and codes that appeared in 2022, such as too_fast_travel and feed_expiration_date, stopped appearing and codes with narrower names took their place. A pass rate measured across validator versions is measuring the validator as much as the feeds.

The other confound is structural, and Cal-ITP says so on every page. In the August 2026 report, 34 of 178 agencies get their schedule from the Bay Area 511 regional feed, and when that feed has any error, every one of them fails. No agency in that group has passed in any month since August 2022, apart from two isolated agency-months. The error observed for 26 of the 34 is missing_required_column, and the regional feed’s producer is MTC, whose GTFS+ specification defined the older rider_categories.txt. We could not run the regional feed ourselves, since its operator feeds sit behind an API key and are outside the open catalog, so that is an inference from three facts rather than a report we have read. Excluding the 511 group, 83 percent of California agencies passed in August 2026, up from 40 percent in December 2022. Our own census gives a check on that figure: of the 132 California feeds we could fetch, which excludes the 511 operators, 114 had no errors, 86 percent.

Vendor clusters show up the same way at smaller scale. In the August report, 16 agencies list a GMV-produced schedule feed as their source, and 11 of them fail, 10 on decreasing_or_equal_stop_time_distance, the shape-distance bookkeeping error. That looks like one bug in one export path counted ten times. Of the 111 agencies present in all 50 monthly reports, six have passed every month (Amador, Glendale, Nevada County, Santa Maria, Santa Clarita, Cudahy) and four have failed every month: Long Beach Transit, North County Transit District, San Diego MTS, and Burbank. Long Beach, North County and San Diego MTS fail on shape-distance codes now as they did in 2022, and Burbank has carried the same decreasing_or_equal_stop_time_distance error in every report.

The other guideline checks put the validator in proportion. In August 2026, 176 of 178 feeds downloaded, 143 were at a stable URL, 146 were in Google Maps or an equivalent, and 67 carried an open license. Fewer agencies clear the license check than clear the validator.

Running it yourself

For one feed, the web validator is enough. For more than one, the jar is the tool: download it from the release page and run it with the input, an output directory, and the country code, since without the country the phone-number rule stays silent. Pass a date if the run needs to be reproducible, because the expiration and coverage warnings are computed against today. On a 12-core laptop the census took a median of 1.9 seconds per feed and 20.7 seconds for the largest, Chicago’s 68.7 MB feed; the whole 1.1 GB took about a quarter of an hour on four workers.

java -jar gtfs-validator-8.0.1-cli.jar -i feed.zip -o out/ -c US -d 2026-09-29

Read report.json rather than the HTML if the result feeds a pipeline, and decide in the pipeline what to do about errors, because the jar will not. Disclosure: ITS Feed’s publisher, Veodyn, maintains a pure-Python reimplementation of the same rule set for pipelines that would rather not carry a Java runtime. We ran it alongside the jar on the census feeds; on the 168 feeds it had finished when this was written it produced the same notice codes, severities and counts as v8.0.1 on all 168, and on the larger feeds it is several times slower. The Java validator is the canonical one and the reference for everything in this piece.

What to watch

The rulebook will keep growing, and each growth spurt fails feeds that did not change. GTFS adopted Flex in 2024 and the validator polices it with dozens of dedicated rules; Fares v2 produced the rider categories collision in 2025; v8 added checks for contactless payment fields and seven new service-window notices. Already 58 of the 736 feeds carry a rider_categories.txt of one lineage or the other, and every regional extension that shares a name with a future official file is a failure waiting for a merge.

Staleness is the thing the validator is worst at communicating. A quarter of the feeds we could fetch describe no service in the coming week, and the tool files that under warnings, next to a stop name in capitals. Anyone using “no errors” as a fitness test, which is what California’s program does, is not testing for the failure mode riders hit.

And the catalog itself rots at a rate worth knowing. Of the 828 URLs, 92 did not return a zip: 38 answered 404, 18 answered 403, 12 would not connect, 11 served an HTML page, 4 loop on a redirect at a Trillium hostname, and 9 sit behind a key. The HTML pages include five where Caltrans’s own hosting returns a landing page where the catalog promises a file. For 79 of the 92, MobilityData’s mirror still holds a copy, so a consumer that reads the mirror sees a feed and a consumer that reads the agency’s URL sees nothing, and the catalog marks both as live. We found the same pattern in the real-time catalog earlier this month.

All counts are point in time: catalog snapshot 2026-08-21, feeds fetched and validated 2026-09-29 with v8.0.1, California pages read the same day. They describe feeds, not agencies.

Common questions

What is the GTFS validator?
The canonical GTFS Schedule validator is a free, open-source Java program maintained by MobilityData. It reads a GTFS zip and reports every place the feed breaks the GTFS Schedule Reference or departs from the published best practices. The v8.0.1 release of 2026-05-12 defines 181 notice codes across three severities. It runs in a browser at gtfs-validator.mobilitydata.org, as a desktop app, as a command-line jar, and as a Docker image.
What is the difference between an ERROR, a WARNING and an INFO notice?
An ERROR marks a violation of something the GTFS Schedule Reference says is required or forbidden. A WARNING marks a departure from a best practice, something the reference says a feed should do. An INFO notice flags something worth a look that is not wrong, such as a file or column the spec does not define. California's compliance check, the only program we found that uses the validator as a pass or fail line, acts on errors alone.
How many GTFS feeds fail the validator?
In a census run on 2026-09-29, 103 of 736 live US feeds from the Mobility Database catalog carried at least one ERROR notice, about 14 percent. Only 21 produced no notices of any kind. Almost every feed carried warnings: 688 of 736.
What is the most common GTFS validation error?
In the same census the single most common error was a missing required column in rider_categories.txt, found in 30 feeds. That file entered GTFS in February 2025 as part of Fares v2. A Bay Area regional extension had used the same filename with different columns since 2011, and feeds still carrying the older file now fail on it.
Does a feed with validation errors still work in Google Maps?
It can. Google runs its own import checks on the Transit Partner Dashboard, a separate list from the canonical validator's. In Cal-ITP's August 2026 report, 146 of 178 California agencies were marked as ingested by Google Maps or an equivalent while 120 passed the validator, so at least 26 agencies with validator errors were being served; the ingestion check is one Cal-ITP marks by hand. The command-line validator's exit code is 0 whether or not the feed has errors, so nothing downstream breaks unless a pipeline reads the report and acts on it.
Does a GTFS feed have to pass the validator for the National Transit Database?
FTA requires fixed-route NTD reporters to maintain a public GTFS feed and submit a link to it, and California's transit data guidelines list that as a mandate. The guideline that the feed regularly passes the canonical validator with no errors is a Caltrans check, which Cal-ITP monitors monthly, not a federal rule.