GTFS Express Open GTFS Express

GTFS validation rules

The 178 rules of the MobilityData validator applied by GTFS Express, with what each one checks.

Errors (117)

bidirectional_exit_gate Detailed page
A pathway with pathway_mode=7 (exit gate) declares is_bidirectional=1: exit gates are unidirectional by definition.
block_trips_with_overlapping_stop_times Detailed page
Two trips sharing the same block_id have overlapping stop_time intervals on a common service day: physically impossible vehicle chaining.
csv_parsing_failed Detailed page
A CSV file could not be parsed: malformed quoting, encoding error, or I/O failure.
decreasing_or_equal_shape_pt_sequence Detailed page
Within a shape, shape_pt_sequence does not strictly increase across consecutive rows after sorting.
decreasing_or_equal_stop_sequence Detailed page
Within a trip, stop_sequence does not strictly increase across consecutive rows after sorting.
decreasing_or_equal_stop_time_distance Detailed page
shape_dist_traveled is not strictly increasing between two consecutive stop_times of the same trip.
decreasing_shape_distance Detailed page
shape_dist_traveled decreases across consecutive shape points.
decreasing_stop_time Detailed page
A stop_times arrival_time is earlier than the previous departure_time on the same trip: time travel.
duplicate_geo_json_key Detailed page
A feature id is repeated within the same locations.geojson file: feature ids must be unique.
duplicate_geography_id Detailed page
A locations.geojson feature id collides with a stop_id (or location_group_id): geography ids must be unique across stops.txt, locations.geojson and location_groups.txt.
duplicate_key Detailed page
Primary-key column has duplicate values (agency_id, stop_id, route_id, trip_id, service_id, …).
duplicated_column Detailed page
Two columns in the same CSV file share the same name.
empty_column_name Detailed page
A CSV header contains an empty cell: column name is missing.
empty_file Detailed page
A GTFS file has zero data rows (header only, or completely empty).
equal_shape_distance_diff_coordinates Detailed page
Two consecutive points share the same shape_dist_traveled but different coordinates: distance metric is inconsistent.
fare_product_with_multiple_default_rider_categories Detailed page
A fare_product references more than one rider category with is_default_fare_category=1: at most one default rider category is allowed per product.
fare_transfer_rule_duration_limit_type_without_duration_limit Detailed page
A fare_transfer_rules row sets duration_limit_type without duration_limit: both fields are conditionally required together.
fare_transfer_rule_duration_limit_without_type Detailed page
A fare_transfer_rules row sets duration_limit without duration_limit_type: both fields are conditionally required together.
fare_transfer_rule_invalid_transfer_count Detailed page
A fare_transfer_rules.transfer_count is not -1 (unlimited) or a positive integer.
fare_transfer_rule_missing_transfer_count Detailed page
A fare_transfer_rules row has from_leg_group_id equal to to_leg_group_id but no transfer_count: required for symmetric transfers.
fare_transfer_rule_with_forbidden_transfer_count Detailed page
A fare_transfer_rules row sets transfer_count when from_leg_group_id differs from to_leg_group_id: transfer_count is forbidden for asymmetric transfers.
forbidden_arrival_or_departure_time Detailed page
A Flex stop_times row that targets a location_id or location_group_id sets arrival_time / departure_time. These columns are forbidden when the trip serves a zone or stop group instead of a fixed stop.
forbidden_continuous_pickup_drop_off Detailed page
continuous_pickup or continuous_drop_off ≠ 1 used together with window fields: conditionally forbidden.
forbidden_drop_off_type Detailed page
drop_off_type=0 used together with window fields: conditionally forbidden.
forbidden_geography_id Detailed page
Catalogue-only entry for canonical-tool compatibility (semantics deferred).
forbidden_pickup_type Detailed page
pickup_type=0 or 3 (regular / coordinate-with-driver) used together with start/end_pickup_drop_off_window: these are conditionally forbidden.
forbidden_prior_day_booking_field_value Detailed page
A booking_rules.txt row with booking_type=2 (prior-day notice) carries a prior_notice_duration_min/max field reserved for the same-day flow.
forbidden_prior_notice_start_day Detailed page
A booking_rules.txt row carries prior_notice_start_day on a booking_type that does not allow it.
forbidden_prior_notice_start_time Detailed page
A booking_rules.txt row carries prior_notice_start_time on a booking_type that does not allow it.
forbidden_real_time_booking_field_value Detailed page
A booking_rules.txt row with booking_type=0 (real-time) carries a prior_notice_* field. Real-time booking rules accept no advance-notice configuration.
forbidden_same_day_booking_field_value Detailed page
A booking_rules.txt row with booking_type=1 (same-day notice) carries a prior_notice_last_* or prior_notice_start_* field reserved for the prior-day flow.
forbidden_shape_dist_traveled Detailed page
A stop_times row sets shape_dist_traveled but the parent trip declares no shape_id (or shapes.txt is empty).
foreign_key_violation Detailed page
A reference to another file's primary key cannot be resolved (route_id → routes, service_id → calendar/calendar_dates, agency_id → agency, …).
geo_json_duplicated_element Detailed page
A feature property is declared more than once (case-insensitive collision): only the last occurrence is kept by JSON parsers.
inconsistent_agency_timezone Detailed page
Multiple agencies declare different timezones: the spec mandates a single timezone across all agencies in a feed.
invalid_boolean_value Detailed page
A boolean field (calendar weekday columns, exact_times, is_bidirectional, …) has a value other than 0 or 1.
invalid_color Detailed page
A color field is not a 6-digit uppercase or lowercase hex string (route_color, route_text_color).
invalid_currency Detailed page
A currency field does not contain a valid ISO 4217 alpha-3 currency code (e.g. USD, EUR, JPY).
invalid_currency_amount Detailed page
A currency-amount field is malformed or has more decimal places than the ISO 4217 minor-unit precision allows for the declared currency (e.g. 1.234 USD, 100.5 JPY).
invalid_date Detailed page
A date field is not in YYYYMMDD format.
invalid_exact_times Detailed page
exact_times is not 0 or 1.
invalid_feed_end_date Detailed page
feed_end_date is not in YYYYMMDD format.
invalid_feed_start_date Detailed page
feed_start_date is not in YYYYMMDD format.
invalid_geometry Detailed page
A polygon or multipolygon in locations.geojson has malformed coordinates (non-finite values, points out of lon/lat range, ring shorter than 4 points, or unclosed ring).
invalid_headway Detailed page
headway_secs is not a positive integer.
invalid_language_code Detailed page
A language field does not match a pragmatic BCP 47 pattern (full IANA registry lookup is not enforced).
invalid_phone_number Detailed page
A phone number field does not parse as a valid international or country-scoped phone number.
invalid_pickup_drop_off_window Detailed page
start_pickup_drop_off_window is greater than or equal to end_pickup_drop_off_window on a Flex stop_times row.
invalid_prior_notice_duration_min Detailed page
prior_notice_duration_min is not a non-negative integer, or it is greater than prior_notice_duration_max.
invalid_row_length Detailed page
A data row's column count does not match the header column count.
invalid_shape_lat Detailed page
shape_pt_lat is missing or not in [-90, 90].
invalid_shape_lon Detailed page
shape_pt_lon is missing or not in [-180, 180].
invalid_time Detailed page
A time field does not match the GTFS HH:MM:SS format (hours may exceed 24:00:00 to encode service-day overflow).
invalid_timezone Detailed page
A timezone field is not a valid IANA tz database identifier (validated via Intl.DateTimeFormat).
invalid_transfer_type Detailed page
transfer_type is not 0-5.
invalid_url Detailed page
A URL field does not parse as an absolute http(s) URL.
location_with_unexpected_stop_time Detailed page
A Flex stop_times row sets BOTH stop_id and (location_id or location_group_id): exactly one must be set.
location_without_parent_station Detailed page
A location_type=2/3/4 (entrance, generic node, boarding area) has no parent_station: these types must be attached to a station.
malformed_json Detailed page
locations.geojson cannot be parsed as JSON: syntactically invalid file.
missing_calendar_and_calendar_date_files Detailed page
Both calendar.txt and calendar_dates.txt are absent: service definitions are required.
missing_feed_info_lang Detailed page
feed_info.feed_lang is empty: required to disambiguate translated string fields.
missing_feed_info_publisher_name Detailed page
feed_info.feed_publisher_name is empty: required for traceability and open-data portals.
missing_feed_info_publisher_url Detailed page
feed_info.feed_publisher_url is empty: required for traceability and open-data portals.
missing_from_stop_id Detailed page
transfers.txt row is missing from_stop_id.
missing_level_id Detailed page
A pathway or stop references a level_id that is absent from levels.txt.
missing_min_transfer_time Detailed page
transfer_type=2 (min-time transfer) but min_transfer_time is empty.
missing_pickup_or_drop_off_window Detailed page
A Flex stop_times row referencing a location_id or location_group_id is missing start_pickup_drop_off_window or end_pickup_drop_off_window.
missing_prior_day_booking_field_value Detailed page
A booking_rules.txt row with booking_type=2 (prior-day notice) is missing a required prior_notice_last_day or prior_notice_last_time field.
missing_prior_notice_duration_min Detailed page
A booking_rules.txt row with booking_type=1 (same-day notice) does not declare prior_notice_duration_min: required for the same-day flow.
missing_prior_notice_last_day Detailed page
A booking_rules.txt row with booking_type=2 (prior-day notice) does not declare prior_notice_last_day.
missing_prior_notice_last_time Detailed page
A booking_rules.txt row with booking_type=2 (prior-day notice) does not declare prior_notice_last_time.
missing_prior_notice_start_time Detailed page
A booking_rules.txt row carries prior_notice_start_day without the matching prior_notice_start_time.
missing_required_column Detailed page
A required column is absent from a present GTFS file's header.
missing_required_field Detailed page
A required field is empty on a row where the spec mandates a value (e.g. agency_name, stop_id, trip_id, route_id, stop_sequence).
missing_required_file Detailed page
A GTFS file declared mandatory by the spec (agency, routes, stops, trips, stop_times, calendar/calendar_dates) is absent.
missing_stop_name Detailed page
stop_name is empty on a stop where the spec requires it (location_type 0, 1 or 2).
missing_stop_times_record Detailed page
A trip declared in trips.txt has zero rows in stop_times.txt.
missing_to_stop_id Detailed page
transfers.txt row is missing to_stop_id.
missing_trip_edge Detailed page
A trip's first or last stop_times row is missing arrival_time AND departure_time: endpoints must be timed.
new_line_in_value Detailed page
A non-quoted/un-escaped newline is embedded inside a CSV value, which would corrupt parsing in many downstream tools.
number_out_of_range Detailed page
A numeric/enum field is outside its spec-mandated range (pickup_type, drop_off_type, continuous_*, timepoint, direction_id, wheelchair_*, bikes_allowed, ...).
overlapping_frequency Detailed page
Two frequencies.txt rows for the same trip have overlapping [start_time, end_time) intervals.
overlapping_zone_and_pickup_drop_off_window Detailed page
Two Flex stop_times rows on the same trip target the same zone (location_id) within overlapping pickup/drop-off windows.
pathway_to_platform_with_boarding_areas Detailed page
A pathway points to a platform that has child boarding areas: pathway must reach the boarding area, not its parent.
pathway_to_wrong_location_type Detailed page
A pathway endpoint references a stop with an incompatible location_type.
pathway_unreachable_location Detailed page
A station-bound location node has no pathway leading to or from it.
point_near_origin Detailed page
A stop is within ~10 m of (0, 0): Null Island, almost certainly a missing or zeroed coordinate.
point_near_pole Detailed page
A stop or shape point sits within 1° of either geographic pole (|lat| > 89.0°): almost certainly a coordinate-entry typo.
prior_notice_last_day_after_start_day Detailed page
prior_notice_last_day is strictly greater than prior_notice_start_day on a booking_rules.txt row.
route_both_short_and_long_name_missing Detailed page
Neither route_short_name nor route_long_name is provided: at least one is required.
route_networks_specified_in_more_than_one_file Detailed page
A route_id has both a non-empty routes.network_id AND an entry in route_networks.txt. The spec requires exactly one source.
service_without_service_days Detailed page
A calendar.txt service has all weekday columns set to 0 AND no compensating positive calendar_dates exception: the service never runs.
start_and_end_date_out_of_order Detailed page
A start_date is greater than its corresponding end_date (calendar.txt or feed_info.txt).
start_and_end_range_equal Detailed page
A frequencies.txt or timeframes.txt row sets start_time == end_time, defining a zero-duration window. Likely a typo.
start_and_end_range_out_of_order Detailed page
A start_time is greater than or equal to its corresponding end_time on a frequencies.txt row.
station_with_parent_station Detailed page
A location_type=1 (station) declares a parent_station: stations are top-level by spec.
stop_lat_out_of_range Detailed page
stop_lat is not a number in [-90, 90].
stop_lon_out_of_range Detailed page
stop_lon is not a number in [-180, 180].
stop_time_timepoint_without_times Detailed page
A row with timepoint=1 (or empty, defaulting to exact) has neither arrival_time nor departure_time.
stop_time_with_arrival_before_previous_departure_time Detailed page
On the same trip, the arrival_time of a stop_time row is strictly less than the previous row's departure_time.
stop_time_with_departure_before_arrival_time Detailed page
On a single stop_times row, departure_time is strictly less than arrival_time.
stop_time_with_only_arrival_or_departure_time Detailed page
Exactly one of arrival_time / departure_time is provided: the spec requires both or neither.
stop_without_location Detailed page
A location_type=0/1/2 stop is missing stop_lat or stop_lon.
timeframe_only_start_or_end_time_specified Detailed page
A timeframes.txt row sets only one of (start_time, end_time). Both fields must be either both present or both absent.
timeframe_overlap Detailed page
Two timeframes.txt rows in the same timeframe_group_id define overlapping (start_time, end_time) windows for the same service_id.
timeframe_start_or_end_time_greater_than_twenty_four_hours Detailed page
A timeframes.txt start_time or end_time is greater than 24:00:00. Unlike stop_times, timeframes are not allowed to spill past the service-day boundary.
transfer_with_invalid_stop_location_type Detailed page
A transfers.txt row references a stop whose location_type is not platform (0) or station (1).
transfer_with_invalid_trip_and_route Detailed page
A transfers.txt row sets both trip_id and route_id, but the trip's actual route_id does not match.
transfer_with_invalid_trip_and_stop Detailed page
A transfers.txt row sets both trip_id and stop_id, but the stop is not referenced by any stop_times row of the trip.
translation_foreign_key_violation Detailed page
A translation row's record_id does not exist in the referenced table_name.
translation_unexpected_value Detailed page
A translation row references a field_value that does not match the source field: translation key cannot be applied.
trip_distance_exceeds_shape_distance Detailed page
max(stop_times.shape_dist_traveled) on a trip is greater than the haversine length of its shape polyline (over 1 % tolerance).
trip_without_stop_times Detailed page
A trip has no stop_times row: orphan trip.
unsupported_feature_type Detailed page
An object inside locations.geojson features[] does not declare type='Feature'.
unsupported_geo_json_type Detailed page
locations.geojson top-level type is not 'FeatureCollection': GTFS-Flex requires the file to wrap features in a FeatureCollection.
unsupported_geometry_type Detailed page
A locations.geojson feature uses a geometry type other than Polygon or MultiPolygon: GTFS-Flex only supports those two.
wrong_parent_location_type Detailed page
A parent_station references a stop whose location_type is not 1 (station).

Warnings (54)

attribution_without_role Detailed page
An attributions.txt row sets none of is_producer / is_operator / is_authority to 1.
duplicate_fare_media Detailed page
Two distinct fare_media rows share the same (fare_media_name, fare_media_type) tuple: downstream consumers cannot tell them apart.
duplicate_route_name Detailed page
Two distinct routes share both short_name and long_name: likely a data-entry duplicate.
empty_row Detailed page
A CSV row contains only commas (every field empty). Treated as a non-data row and skipped, but signals a likely export bug upstream.
equal_shape_distance_diff_coordinates_distance_below_threshold Detailed page
Two consecutive shape points share shape_dist_traveled and the geographic delta is below 1.11 m: negligible impact.
equal_shape_distance_same_coordinates Detailed page
Two consecutive points share both shape_dist_traveled and coordinates: duplicate point.
expired_calendar Detailed page
An individual calendar.txt service's end_date is in the past.
fast_travel_between_consecutive_stops Detailed page
Two consecutive stop_times rows imply an average speed greater than the route_type's plausible upper bound (e.g. >150 km/h on a bus). Likely a missing stop or a clock error.
fast_travel_between_far_stops Detailed page
A trip's overall average speed (Σ distance / Σ time) exceeds a high threshold even when consecutive segments individually look plausible. Often signals a service discontinuity.
feed_expiration_date_30_days Detailed page
feed_end_date is within 30 days from now.
feed_expiration_date_7_days Detailed page
feed_end_date is within 7 days from now: heads-up for publishers.
feed_expired Detailed page
The feed-level end_date is in the past.
feed_info_lang_and_agency_lang_mismatch Detailed page
feed_info.feed_lang differs from the dominant agency.agency_lang.
inconsistent_agency_lang Detailed page
Multiple agencies declare different languages: interoperability hint.
leading_or_trailing_whitespaces Detailed page
A CSV value protected by double quotes carries leading or trailing whitespace. Quoted whitespace risks breaking key/FK matches when the same id appears with and without padding in different files.
missing_bike_allowance Detailed page
trips.bikes_allowed is empty: recommended for active-mobility consumers.
missing_feed_contact_email_and_url Detailed page
feed_info.txt declares neither feed_contact_email nor feed_contact_url. Consumers cannot reach the publisher to report data issues.
missing_feed_info_date Detailed page
Exactly one of feed_start_date / feed_end_date is provided: both should be supplied together.
missing_pickup_drop_off_booking_rule_id Detailed page
A stop_times row uses pickup_type=2 or drop_off_type=2 (must phone agency) but does not reference a pickup_booking_rule_id / drop_off_booking_rule_id.
A recommended (but not required) field is absent from a row that has the corresponding column declared.
A non-mandatory but strongly recommended file (feed_info.txt) is absent.
missing_timepoint_value Detailed page
stop_times.timepoint is empty: recommended to set 0 (inexact) or 1 (exact) explicitly.
A textual field uses inconsistent casing (e.g. ALL CAPS for stop_name) reducing readability for end users. MobilityData recommends Title Case for human-facing names.
more_than_one_entity Detailed page
feed_info.txt contains more than one row: the spec mandates exactly one.
non_ascii_or_non_printable_char Detailed page
A field contains non-printable control characters (tab, vertical tab, form feed, etc.) or non-ASCII characters that may not survive ASCII-only consumers.
pathway_dangling_generic_node Detailed page
A generic_node (location_type=3) has no boarding-area child or no pathway connection: disconnected node.
pathway_loop Detailed page
from_stop_id and to_stop_id of a pathway are identical: self-loop.
route_color_contrast Detailed page
WCAG sRGB contrast ratio between route_color and route_text_color is below 4.5:1, accessibility concern.
route_long_name_contains_short_name Detailed page
route_long_name token-includes route_short_name (e.g. short=42, long="Bus 42 Centre"): redundant for riders.
route_short_name_too_long Detailed page
route_short_name exceeds 12 characters: short names should fit on signage and timetables.
route_type_invalid Detailed page
route_type is not in the GTFS spec's enum (0-12 plus extended 100-1799 hierarchical types).
route_without_trips Detailed page
A route has no trips assigned to it.
same_name_and_description_for_route Detailed page
route_desc duplicates route_short_name or route_long_name.
same_name_and_description_for_stop Detailed page
stop_desc is identical to stop_name: the description should add information, not repeat the name.
same_route_and_agency_url Detailed page
A route's route_url equals its agency's agency_url. Likely a default-fill bug.
same_stop_and_agency_url Detailed page
A stop's stop_url equals an agency's agency_url. Likely a default-fill bug.
same_stop_and_route_url Detailed page
A stop's stop_url equals some route's route_url. Likely a default-fill bug.
single_shape_point Detailed page
A shape_id has exactly one shape_pt_sequence row. A shape needs at least two points to define a segment.
stop_has_too_many_matches_for_shape Detailed page
More than 5 shape vertices are within the matching threshold of a single stop: ambiguous projection.
stop_time_travel_distance_too_long Detailed page
Distance between two consecutive stops on a trip exceeds 500 km (sanity threshold).
stop_time_travel_speed_too_fast Detailed page
Computed travel speed between consecutive stops exceeds the per-route_type ceiling (100-300 km/h).
stop_too_far_from_shape Detailed page
A stop is more than 100 m from the nearest vertex of its trip's shape polyline.
stop_too_far_from_shape_using_user_distance Detailed page
Variant of stop_too_far_from_shape using shape_dist_traveled: the predicted shape-position is far from the stop's actual coordinates.
stop_without_stop_time Detailed page
A stop is never referenced by any stop_times row: unused boarding location.
stops_match_shape_out_of_order Detailed page
The stops of a trip, projected onto its shape polyline, are not in monotonic increasing order.
transfer_distance_too_large Detailed page
Distance between from_stop and to_stop exceeds 2 km: unrealistic walking transfer.
transfer_with_suspicious_mid_trip_in_seat Detailed page
transfer_type=4 (in-seat continuation) between two trips without a shared block_id: likely modelling error.
translation_unknown_table_name Detailed page
translations.table_name is not a recognised GTFS table.
trip_coverage_not_active_for_next7_days Detailed page
Trip's service_id is inactive for the next 7 days: passengers cannot board it during that window.
trip_distance_exceeds_shape_distance_below_threshold Detailed page
Same condition as trip_distance_exceeds_shape_distance but below the strict tolerance: review recommended.
unusable_trip Detailed page
A trip has fewer than two stop_times rows. The trip cannot be travelled and will be ignored by routing engines.
unused_parent_station Detailed page
Alias of unused_station emitted alongside it for canonical-tool compatibility.
unused_shape Detailed page
A shape_id defined in shapes.txt is not referenced by any trip in trips.txt. The geometry is dead weight in the export ZIP.
unused_trip Detailed page
A trip's service_id is never active in any of the next 7 days from feed_start_date: the trip is currently unreachable.

Information (7)

geo_json_unknown_element Detailed page
An element in locations.geojson is not recognised by the GTFS-Flex profile and will be ignored by canonical consumers.
platform_without_parent_station Detailed page
A platform (location_type=0 or empty) has no parent_station. Recommended for wayfinding.
stop_without_zone_id Detailed page
A platform (location_type=0 or empty) has no zone_id. Recommended for feeds that use fare zoning.
transfer_distance_above_2_km Detailed page
A transfers.txt row links two stops more than 2 km apart: INFO threshold complementary to the 10 km transfer_distance_too_large.
unknown_column Detailed page
A column header in a recognised GTFS file is not declared by the spec for that file. The data in this column will be silently ignored by downstream consumers.
unknown_file Detailed page
A file is present in the feed ZIP but is not part of the GTFS Schedule, GTFS-Flex, or DRT-Booking spec. It will be silently ignored by downstream consumers.
unused_station Detailed page
A station (location_type=1) is not referenced as parent_station by any platform/stop. Stations exist purely to group child stops.