200 with a solution; infeasibility shows up as specific stops or resources being left out of it. This guide covers how to recognize that and work back to the cause.
How to recognize an infeasibility response
There is no dedicated “infeasible” status — check these fields on the solution instead:unaffectedStopIds— non-empty means at least one stop could not be planned within the hard constraints. This is the most common signal and the one to check first.unusedResourceIds— non-empty means at least one resource was left with nothing assigned. This isn’t necessarily a problem (it can beminimizeResourcesdoing its job) — see the third bullet under “Common causes” below before assuming it’s a bug.tours[].isValid: false— a specific tour violates a hard constraint. This is rarer in practice (the engine generally avoids constructing an invalid tour rather than returning one), but check it per-tour rather than assuming the plan is fine because the top-level call succeeded.
Diagnostic method: which constraint is at fault
For each stop inunaffectedStopIds, walk through the hard constraints in Hard vs soft constraints and check them against that stop and the resources that could plausibly serve it:
- Time windows. Is there any resource whose
workingTimeWindowoverlaps at least one of the stop’sauthorizedTimeWindows, once travel time to/from the stop is accounted for? A window that’s technically non-empty but unreachable given travel time is the single most common cause — especially if the window came from apreferredTimeWindowsfield that was accidentally modeled asauthorizedTimeWindows(see Hard vs soft constraints); a window that’s a hard constraint by mistake turns a should-be-late delivery into a dropped one. - Skills. Does any available resource’s
skillsarray cover every one of the stop’s order’srequiredSkills? A single missing skill on every resource is enough to make the stop unserviceable. - Capacities. Does any resource declare every capacity key the stop consumes, with enough remaining headroom at that point in a plausible tour? Remember capacities are free-form — a typo in a key name (
weightvsWeight) silently makes the stop unmatchable to every resource, with no error raised. - Order structure. If the order has
successiveStopsor amaxStopSpan, check whether the timing implied by other constraints (time windows, breaks) makes that structural requirement impossible to satisfy alongside them. - Resource-level bounds. Would serving this stop push a resource over its
maxWorkingDuration,maxDistanceInKm, ormaxInterStopDistanceInKm/maxInterStopDuration?
Resolution strategies
Once you’ve identified the binding constraint, the fix is usually one of:- Relax the constraint, if it was set stricter than the business actually requires — the most common example is switching a contractual delivery window from
authorizedTimeWindowstopreferredTimeWindowsonce you confirm a late visit is acceptable. - Add or reassign a resource — a stop with no resource combination that satisfies its skills/capacity/time-window requirements simply needs one that does; this is a fleet-sizing problem more than a modeling one.
- Lower the stop’s
priorityor mark it"optional": trueif it’s acceptable for it to be dropped under pressure from higher-priority stops — this doesn’t fix infeasibility, but it makes the trade-off explicit and intentional instead of an unplanned side effect. - Check
additionalConstraints/globalConstraints(incompatibleStopTags,forbiddenAssignment,maxStopTagGroups,maxCumulatedCost, etc.) for anything scoped to the stop’s or resource’s tags — these are easy to forget once a plan has grown past its first few constraints.
See also
- Hard vs soft constraints — the conceptual explanation of which fields are walls and which are targets, referenced throughout the diagnostic method above.
- Data model — full field reference for everything checked in the diagnostic steps.
- Modeling advanced constraints — worked examples for capacities, skills, breaks, and multiple time windows.

