# Failsafe

URL: /rules/failsafe-entered

Flags the moment PX4 reports a failsafe in vehicle_status, with the cause from failsafe_flags and the mode PX4 chose. It observes PX4's decision, which PX4 times on its own status reports.



<RuleHeader id="failsafe_entered" />

## What it reads [#what-it-reads]

The rule reads two topics from the flight log:

* `vehicle_status.failsafe`: true while PX4 is in a failsafe state.
* `vehicle_status.nav_state`: the mode now active.
* `failsafe_flags`: one flag per condition. The rule takes the cause from the flag that is set, such as `gcs_connection_lost`.

```text title="VehicleStatus.msg" caption="PX4 v1.16.0, abridged"
uint8 nav_state                                 # Currently active mode
uint8 NAVIGATION_STATE_AUTO_LOITER = 4          # Auto loiter mode
uint8 NAVIGATION_STATE_AUTO_RTL = 5             # Return mode
bool failsafe # true if system is in failsafe state (e.g. Return, Hover, Terminate, ...)
```

In PX4 v1.16.0 the commander sets `failsafe` while its failsafe state machine has selected an action other than none or a warning. The action for each condition comes from a parameter:

| Flag in `failsafe_flags`       | Action set by                           | Example dataset                          |
| ------------------------------ | --------------------------------------- | ---------------------------------------- |
| `gcs_connection_lost`          | `NAV_DLL_ACT`, after `COM_DL_LOSS_T`    | 1 (Hold) on the T4, 2 (Return) on the Q4 |
| `offboard_control_signal_lost` | `COM_OBL_RC_ACT`, after `COM_OF_LOSS_T` | 5 (Hold)                                 |
| `gnss_lost`                    | `COM_GNSSLOSS_ACT`                      | 0 (Warning)                              |

The vehicle page lists these values under **Failsafe parameters**, with the run they were read from.

## When it fires [#when-it-fires]

The threshold reads **Any failsafe**: a finding is produced each time `vehicle_status.failsafe` turns true. The event records the cause, the action and how long PX4 took to act. In INC-0143 its title reads **GCS connection loss: switching to Hold**, the wording PX4 uses for a failsafe with a cause.

### How PX4 times a lost ground link [#how-px4-times-a-lost-ground-link]

PX4's MAVLink receiver keeps `heartbeat_type_gcs` true in `telemetry_status` until 2.5 s pass without a ground station heartbeat (`HEARTBEAT_TIMEOUT_US`). It re-evaluates the flag on every heartbeat from a ground station or from its own system. Between heartbeats, it checks again once 1.25 s have passed since the last check.

The status topic goes out at least once a second, and the commander restarts its timer on every report that still says true. `COM_DL_LOSS_T` therefore counts from the last report with the heartbeat, not from the heartbeat:

```cpp title="src/modules/commander/Commander.cpp" caption="PX4 v1.16.0, Commander::dataLinkCheck(), abridged"
if (telemetry.heartbeat_type_gcs) {
	...
	_datalink_last_heartbeat_gcs = telemetry.timestamp;
}
...
// GCS data link loss failsafe
if (!_vehicle_status.gcs_connection_lost) {
	if ((_datalink_last_heartbeat_gcs != 0)
	    && hrt_elapsed_time(&_datalink_last_heartbeat_gcs) > (_param_com_dl_loss_t.get() * 1_s)) {

		_vehicle_status.gcs_connection_lost = true;
```

`COM_DL_LOSS_T` is 10 s by default, from 5 s to 300 s. With the default, the failsafe lands about 11.5 s to 13.75 s after the last heartbeat, depending on how heartbeats and reports happen to fall.

<Figure caption="How PX4 reached Hold in INC-0143. Offsets run from the last ground station heartbeat PX4 handled, at 15:41:02.412. COM_DL_LOSS_T counts its 10 s from the last telemetry_status that still reported that heartbeat, 1.874 s later.">
  <LinkLossTimer />
</Figure>

### How PX4 chooses the action [#how-px4-chooses-the-action]

`NAV_DLL_ACT` selects what PX4 does once the ground link counts as lost. PX4's default is 0, which takes no action at all.

| `NAV_DLL_ACT` | Action      |
| ------------- | ----------- |
| 0             | Disabled    |
| 1             | Hold mode   |
| 2             | Return mode |
| 3             | Land mode   |
| 5             | Terminate   |
| 6             | Disarm      |

`COM_FAIL_ACT_T`, 5 s by default, makes PX4 hold before it enters a Return or a Land. Hold itself is never delayed, and neither are Disarm and Terminate:

```cpp title="framework.cpp" caption="PX4 v1.16.0, FailsafeBase::getSelectedAction(), abridged"
// Check if we should enter delayed Hold
const bool action_can_be_delayed = selected_action != Action::None &&
				   selected_action != Action::Warn &&
				   selected_action != Action::Disarm &&
				   selected_action != Action::Terminate &&
				   selected_action != Action::Hold;
```

## Wording and evidence level [#wording-and-evidence-level]

Every finding reads **Observed: failsafe entered, with its cause**. The flight log shows directly that PX4 entered a failsafe and which flag it acted on, so the level is observed.

## What the finding does not mean [#what-the-finding-does-not-mean]

* **A late-looking failsafe is not a fault.** A Hold 11.88 s after the last heartbeat, with `COM_DL_LOSS_T` at 10 s, is PX4 counting from its last status report as designed.
* **It does not say why the link was lost.** The flag records what PX4 stopped hearing, not what broke. In INC-0143 the radio left the companion's USB bus, which [device\_disconnect](/rules/device-disconnect) records.
* **A set flag with no action is not a failsafe.** With `NAV_DLL_ACT` at 0 (Disabled), PX4 does not treat a lost ground link as a failsafe, so `failsafe` stays false. INC-0137 ran that way by its test plan: the flight log shows `gcs_connection_lost`, PX4 continued the mission and this rule produced nothing.
* **Warnings never produce it.** PX4 sets `failsafe` only for actions beyond a warning. The example vehicles run `COM_GNSSLOSS_ACT` at 0 (Warning), so a GNSS loss on them raises no failsafe.
* **PX4 ignores some losses.** In v1.16.0 a lost ground link triggers nothing while the vehicle is disarmed or landing, including a precision landing. The same holds in any mode listed in `COM_DLL_EXCEPT`.
* **The first mode can differ from the action.** With `NAV_DLL_ACT` at 2 (Return), the example Q4 setting, PX4 first holds for `COM_FAIL_ACT_T`, 5 s in the example, then returns. Read the `nav_state` records after the finding.

## Threshold and overrides [#threshold-and-overrides]

The threshold is **Any failsafe**, applied to **All vehicles**. The rule has no number of its own to tune, because PX4's parameters decide when a failsafe happens. The vehicle page's **Changes between runs** drawer shows when those parameters change, for example `NAV_DLL_ACT` 0 (Disabled) to 1 (Hold) on UGV-05 in R-0924.

Change the scope under **Rules** with **Edit**; the rule saves as `failsafe_entered 1.1`. See [Thresholds, scopes and overrides](/rules/configure).

## Example finding [#example-finding]

In INC-0143, UGV-02's radio dropped off the companion's USB bus at 15:41:02.604 in Breach lane 2. PX4 had handled the last ground station heartbeat at 15:41:02.412. The last `telemetry_status` that still reported it came at 15:41:04.286, and the first without it at 15:41:05.286.

`COM_DL_LOSS_T` ran out at 15:41:14.286, and PX4 switched to Hold at 15:41:14.293. That is 11.88 s after the last heartbeat (15:41:14.293 minus 15:41:02.412) and 10.01 s after the last report (15:41:14.293 minus 15:41:04.286). The vehicle stopped 1.0 s later, and range control resumed the mission 56.2 s after the Hold.

The **Findings** row labels the finding **Failsafe: Hold**. On the event page, **Failsafe decision** walks through the same steps on the flight log clock, each with the PX4 source it follows. Its **Parameters in effect** list reads `COM_DL_LOSS_T` 10 s, `NAV_DLL_ACT` 1 (Hold) and `COM_FAIL_ACT_T` 5 s (not applied to Hold).

INC-0142 shows the opposite case. PX4 reported no ground station heartbeat on TELEM2 at 14:32:06.510, but the receive gap lasted 6.96 s, under `COM_DL_LOSS_T`. PX4 recorded no failsafe, and this rule produced nothing.

## Related [#related]

* [telemetry\_gap](/rules/telemetry-gap) reports the same loss as heard at range control.
* [device\_disconnect](/rules/device-disconnect) records the radio leaving the USB bus in INC-0143.
* [PX4 parameters Foxborne reads](/reference/px4-parameters) lists `COM_DL_LOSS_T`, `NAV_DLL_ACT` and the rest.
* [Vehicles and parameter drift](/investigate/vehicle) shows each vehicle's failsafe parameters.
