Validate your GTFS feed. Know what to fix.
Check schedules, stops and routes for errors before publication. You get a report that names the affected file, row and field for every issue — and what to change.
Drop a GTFS.zip here
Up to 150 MB zipped / 700 MB unpacked. Larger feeds: use the desktop app or the CLI.
The browser downloads the archive first. If the host blocks that, gtfs.guru fetches it for you — so a URL feed passes through our server, unlike a file you pick. How URL validation handles data.
What the report checks
110 validators over the whole feed, each finding reported with the file, row and field behind it.
Structure
Required files and columns are present, the archive parses as CSV, and no required value is blank.
References
Every trip_id, stop_id, route_id and
service_id resolves to a row that actually exists.
Schedules
Times are valid and move forward along each trip, service periods are the right way round, and calendars still cover the dates you publish.
Geography
Coordinates are plausible, stops sit near the shape that serves them, and travel between consecutive stops is physically possible.
Presentation
Route names, colours, contrast, URLs and phone numbers are the ones riders will actually see in an app.
Fares and pathways
Fares v2 products and transfer rules, station hierarchies and in-station pathways hold together.
Every check has a page explaining what it means and how to repair it. Browse all 191 notice codes.
How it compares with the canonical Java validator
A separate Rust implementation with closely compatible notice codes — the rule sets are not identical. See exactly where they differ.
| Feature | Canonical Java Validator | GTFS Guru (Rust) |
|---|---|---|
| MBTA Boston 38 MB zip, 5.4M stop_times rows |
10.60s | 2.32s (4.6x faster) |
| OVapi Netherlands 198 MB zip, 16.0M stop_times rows |
65.18s | 9.75s (6.7x faster) |
| Small feed 295-case test corpus, median 1.6 KB |
1.274s | 0.016s (88x faster, median) |
| Memory use peak, OVapi NL run |
~1.5GB RAM | ~150MB RAM |
| Rule set | Canonical reference | Closely compatible, not identical |
| Where it runs | JVM: CLI, desktop, hosted service | Browser, desktop, CLI, Python, CI |
| Python support | Wrapper only | Native (pip install) |
| CI output | JSON / HTML reports | SARIF, JSON, HTML + GitHub Action |
Large-feed rows: Apple M3 Pro, warm page cache, both tools running their full pipeline with 8 threads and writing their normal report files (gtfs.guru n=5, canonical validator 8.0.1 n=3 under OpenJDK 21). Small-feed row: every one of the 295 feeds in the project's test corpus, 3 runs each, median kept — across them the speed-up ranges from 28x to 196x, and 43% of the cases are at or above 100x, because on a feed this size the JVM's startup is most of the run. Rule sets and report formats differ between the two tools, so these are whole-run comparisons, not per-rule ones — your own numbers will depend on your feed and machine. Full method and commands to reproduce.
Get the Desktop App
The easiest way to validate feeds on your machine.
For Developers
Validate feeds from Python, the command line, or CI.
Python Package
pip install gtfs-guru
import gtfs_guru
report = gtfs_guru.validate("data.zip")
if not report.is_valid:
print(f"Found {report.error_count} errors")
report.save_html("report.html")
Rust CLI
cargo install gtfs-guru
gtfs-guru -i ./feed.zip -o ./dist
# Output JSON for CI/CD
gtfs-guru --stdout -i feed.zip | jq .
Which GTFS revision this validator answers for
The compatibility page names the exact GTFS reference revision and the MobilityData validator release this version is aligned with, lists what changed upstream recently, and maps every notice code to its canonical rule.
Ask questions about a checked feed
GTFS Guru returns exact totals and concrete examples with available file, row, field, and context, so the answer stays grounded in the validator report.
Frequently Asked Questions
Everything you need to know about GTFS Guru.
What is a GTFS validator?
Think of it as a spell-checker for transit data. A validator catches errors in your feed before you submit it to apps like Google Maps or Apple Maps. GTFS Guru reports them with the file, row and field so you can go straight to the fix.
Is GTFS Guru free?
Yes. GTFS Guru is free and open source under the Apache 2.0 licence. Whether you're using the web validator, the desktop app, or our libraries, there are no costs, no usage limits, and no hidden "premium" versions.
Is my transit data safe when I validate it?
A file you choose or drop is read by your browser and validated there by WebAssembly — it is never uploaded, and we never see it. The desktop app and CLI work the same way. One case differs: if you validate by URL and the feed host blocks your browser's direct download, the page retries through gtfs.guru, so the archive passes through our server in memory for that one request before your browser validates it. Both paths, in detail.
How is GTFS Guru different from the canonical Java validator?
It is a separate Rust implementation inspired by the canonical Java validator, not a port of it. The report shape and the notice codes are closely compatible, but the rule sets are not identical — the compatibility page lists where they diverge. On speed, published benchmarks (Apple M3 Pro, warm page cache, 8 threads) measure 4.6–6.7x faster than the canonical validator 8.0.1 on large feeds: 2.32s versus 10.60s on the MBTA feed and 9.75s versus 65.18s on the OVapi Netherlands feed, using roughly 150 MB of memory instead of 1.5 GB. On small feeds the gap is much wider, because JVM startup is most of the run: across the project's 295-feed test corpus the median speed-up is 88x, 43% of cases exceed 100x and the widest is 196x. It also runs where the Java validator cannot: in a web browser and as a native Python package.
Can I run GTFS validation in CI?
Yes. The GitHub Action
abasis-ltd/gtfs.guru/action validates a feed on every push, uploads SARIF so
findings appear in the GitHub Security tab, and fails the job when the feed reaches a
chosen severity. The CLI supports the same gate with --fail-on error, and can
emit a shields.io status badge with --badge.
How do I get my routes on Google Maps?
It's a three-step process: Create a GTFS feed, use GTFS Guru to make sure it's error-free, and then submit it through the Google Transit Partner Dashboard. Having a clean, validated file is the best way to speed up publication.
Is there a file size limit for the browser validator?
The browser validator handles feeds up to 150 MB zipped (700 MB unpacked) directly in your browser. Larger files can hit browser memory limits, so for those, use the desktop app or the CLI, which are not bound by browser memory.
Need more technical details or step-by-step guides?
View In-Depth Guides