Index: src/aircraft_cmd.cpp
===================================================================
--- src/aircraft_cmd.cpp	(revision 27930)
+++ src/aircraft_cmd.cpp	(working copy)
@@ -2085,7 +2085,19 @@
 	FOR_ALL_AIRCRAFT(v) {
 		if (!v->IsNormalAircraft() || v->targetairport != st->index) continue;
 		assert(v->state == FLYING);
+
+		Order *o = &v->current_order;
+		/* The aircraft is heading to a hangar, but the new station doesn't have one,
+		 * or the aircraft can't land on the new station. Cancel current order. */
+		if (o->IsType(OT_GOTO_DEPOT) && !(o->GetDepotOrderType() & ODTFB_PART_OF_ORDERS) && o->GetDestination() == st->index &&
+				(!st->airport.HasHangar() || !CanVehicleUseStation(v, st))) {
+			o->MakeDummy();
+			SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
+		}
 		v->pos = v->previous_pos = AircraftGetEntryPoint(v, ap, rotation);
 		UpdateAircraftCache(v);
 	}
+
+	/* Heliports don't have a hangar. Invalidate all go to hangar orders from all aircraft. */
+	if (!st->airport.HasHangar()) RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, st->index, true);
 }
Index: src/order_backup.cpp
===================================================================
--- src/order_backup.cpp	(revision 27930)
+++ src/order_backup.cpp	(working copy)
@@ -256,8 +256,11 @@
  * Removes an order from all vehicles. Triggers when, say, a station is removed.
  * @param type The type of the order (OT_GOTO_[STATION|DEPOT|WAYPOINT]).
  * @param destination The destination. Can be a StationID, DepotID or WaypointID.
+ * @param hangar Only used for airports in the destination.
+ *               When false, remove airport and hangar orders.
+ *               When true, remove either airport or hangar order.
  */
-/* static */ void OrderBackup::RemoveOrder(OrderType type, DestinationID destination)
+/* static */ void OrderBackup::RemoveOrder(OrderType type, DestinationID destination, bool hangar)
 {
 	OrderBackup *ob;
 	FOR_ALL_ORDER_BACKUPS(ob) {
@@ -264,7 +267,7 @@
 		for (Order *order = ob->orders; order != NULL; order = order->next) {
 			OrderType ot = order->GetType();
 			if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue;
-			if (ot == OT_IMPLICIT || (IsHangarTile(ob->tile) && ot == OT_GOTO_DEPOT)) ot = OT_GOTO_STATION;
+			if (ot == OT_IMPLICIT || (IsHangarTile(ob->tile) && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION;
 			if (ot == type && order->GetDestination() == destination) {
 				/* Remove the order backup! If a station/depot gets removed, we can't/shouldn't restore those broken orders. */
 				delete ob;
Index: src/order_backup.h
===================================================================
--- src/order_backup.h	(revision 27930)
+++ src/order_backup.h	(working copy)
@@ -63,7 +63,7 @@
 
 	static void ClearGroup(GroupID group);
 	static void ClearVehicle(const Vehicle *v);
-	static void RemoveOrder(OrderType type, DestinationID destination);
+	static void RemoveOrder(OrderType type, DestinationID destination, bool hangar);
 };
 
 /**
Index: src/order_cmd.cpp
===================================================================
--- src/order_cmd.cpp	(revision 27930)
+++ src/order_cmd.cpp	(working copy)
@@ -1833,8 +1833,11 @@
  * Removes an order from all vehicles. Triggers when, say, a station is removed.
  * @param type The type of the order (OT_GOTO_[STATION|DEPOT|WAYPOINT]).
  * @param destination The destination. Can be a StationID, DepotID or WaypointID.
+ * @param hangar Only used for airports in the destination.
+ *               When false, remove airport and hangar orders.
+ *               When true, remove either airport or hangar order.
  */
-void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination)
+void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar)
 {
 	Vehicle *v;
 
@@ -1847,7 +1850,7 @@
 		Order *order;
 
 		order = &v->current_order;
-		if ((v->type == VEH_AIRCRAFT && order->IsType(OT_GOTO_DEPOT) ? OT_GOTO_STATION : order->GetType()) == type &&
+		if ((v->type == VEH_AIRCRAFT && order->IsType(OT_GOTO_DEPOT) && !hangar ? OT_GOTO_STATION : order->GetType()) == type &&
 				v->current_order.GetDestination() == destination) {
 			order->MakeDummy();
 			SetWindowDirty(WC_VEHICLE_VIEW, v->index);
@@ -1861,7 +1864,7 @@
 
 			OrderType ot = order->GetType();
 			if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue;
-			if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT)) ot = OT_GOTO_STATION;
+			if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION;
 			if (ot == type && order->GetDestination() == destination) {
 				/* We want to clear implicit orders, but we don't want to make them
 				 * dummy orders. They should just vanish. Also check the actual order
@@ -1895,7 +1898,7 @@
 		}
 	}
 
-	OrderBackup::RemoveOrder(type, destination);
+	OrderBackup::RemoveOrder(type, destination, hangar);
 }
 
 /**
Index: src/order_func.h
===================================================================
--- src/order_func.h	(revision 27930)
+++ src/order_func.h	(working copy)
@@ -17,7 +17,7 @@
 #include "company_type.h"
 
 /* Functions */
-void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination);
+void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar = false);
 void InvalidateVehicleOrder(const Vehicle *v, int data);
 void CheckOrders(const Vehicle*);
 void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist = false, bool reset_order_indices = true);
