Node id must be a virtual node

I try to calculate bus routes using all stop members as via points. This worked fine for the first ~30 stops of relation 35496, but then I encounter the following issue:
Calling GraphHopper.calcPaths with

List<GHPoint> = new ArrayList<>(); 
routePoints.add(new GHPoint(48.6923369,9.118767));
routePoints.add(new GHPoint(48.6920127,9.1225489));
routePoints.add(new GHPoint(48.6923632,9.1292861));

GHRequest request =  new GHRequest(routePoints).setWeighting("fastest").setVehicle("car");
request.getHints().put("edge_based", Boolean.TRUE).put("u_turn_costs", -1).put("pass_through", Boolean.TRUE); 

I got the following Exception:

Caused by: java.lang.IllegalArgumentException: Node id 199570 must be a virtual node.
	at com.graphhopper.routing.QueryGraph.unfavorVirtualEdgePair(
	at com.graphhopper.routing.template.ViaRoutingTemplate.calcPaths(
	at com.graphhopper.GraphHopper.calcPaths(

I built the graph with “car|turn_costs=true” and “”.

Data used: stuttgart-regbez-latest.osm.pbf,, containing all OSM data up to 2019-10-22T20:18:03Z.

GH Version: 13.0

Seems to be an issue or is there anything I should keep in mind?


I’m afraid what you are intending to do is not supported yet (neither in 13.0 nor in recent master). The pass_through parameter is not supported for speed-mode/CH, see here: and can even lead to wrong results (hence the issue: you should get an error saying this).

If you do not use pass_through there can be u-turns at the via points even though you are using edge_based=true. Starting from GH version 1.0-pre2 there is a new feature: curbside that allows you specifying from which side your via point should be reached or left ( If you do this there won’t be u-turns, but I think for your usecase this is rather a workaround. I think what you need is via routing with an option to prevent u-turns at the via points and arriving/leaving the via points in whatever direction leads to the optimal route. This is still work in progress and I opened a ticket for this:

Your other option is using flexible mode (ch.disable=true) in which case pass_through will work, but the routing will of course be slower.

Actually this problem might even exist with flexible mode, because of a rare case where a via point sits on a junction.

I can reproduce this issue even for flexible mode:

Your via point sits directly on a junction (near Filderstr. 53), so basically you are asking to ‘go straight’, but there is more than one option and the routing engine returns an error. But of course it would be better if just any of the options (or even better the best) was chosen or the pass_through would be ignored in this case.

This is a known (and still not fixed) bug:


Thank you very much for your immediate support and analysis!
The hint to #1258 is much appreciated. I submitted a fix that silently ignores this.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.