
Understanding ArduPilot Fence Breach Events in .bin Log Files
Key Takeaway
Fence breach in ArduPilot logs as ERR Subsys=9 with the ECode naming which type tripped. FENCE_TYPE is a bitmask: 1 = altitude ceiling, 2 = circle, 4 = polygon, 8 = altitude floor. FENCE_ACTION (Copter: 0-5) selects the response — default 1 is RTL or Land. The matching MODE transition is Rsn=10 FENCE_BREACHED.
TL;DR: Fence breach events in ArduPilot log as ERR Subsys=9 with an ECode that names which fence type tripped. The FENCE_TYPE parameter is a bitmask of four fence kinds: altitude ceiling (1), circular horizontal (2), polygon (4), and altitude floor (8). When the vehicle crosses any enabled fence, the autopilot writes the error and executes FENCE_ACTION — usually RTL on Copter. Diagnose by reading the breach time, the active fence types, the actual POS and BARO.Alt at that moment, and the resulting MODE transition.
What ArduPilot's fence system actually checks
The FENCE_TYPE parameter is a bitmask. Each bit enables a different boundary check:
1— Altitude ceiling. Triggered when altitude exceedsFENCE_ALT_MAX.2— Circular horizontal. Triggered when horizontal distance from home exceedsFENCE_RADIUS.4— Polygon. Triggered when position crosses an arbitrary user-defined polygonal boundary uploaded via Mission Planner or QGC.8— Altitude floor. Triggered when altitude drops belowFENCE_ALT_MIN(commonly used to prevent flying below terrain).
To enable all four checks, set FENCE_TYPE = 15. To enable only the circle and altitude ceiling, FENCE_TYPE = 3. The bits combine arithmetically.
What happens when a breach fires
The autopilot writes ERR Subsys=9 ECode=N where the ECode names the type that breached, and executes the action set in FENCE_ACTION. On Copter the action values are:
0— Report Only (logged, but no autonomous action).1— RTL, or Land if RTL is not possible. The default.2— Always Land (immediate descent).3— SmartRTL if possible, otherwise RTL or Land.4— Brake or Land (good for static-fence applications where you want to stop, not return).5— SmartRTL if possible, otherwise Land.
On Plane the action values are different (1=RTL, 6=Guided, 7=GuidedThrottlePass, 8=AUTOLAND if possible else RTL).
Reading the breach in Mission Planner
Open the .bin log and:
- Look in the Errors tab for
FAILSAFE_FENCEentries (Subsys 9). The timestamp and ECode tell you which fence type triggered. - Plot
POS.Lat,POS.Lngfor horizontal breaches; plotBARO.Altfor altitude breaches. - The
MODEmessage just after the breach shows the action that fired —Mode=6(RTL) withRsn=10(FENCE_BREACHED) is the most common chain. - The
MSGstream usually contains a textual note such as "Fence: Polygon breached" naming the type for human readers.
Confirming it in MAVExplorer
MAV> messages ERR
MAV> graph POS.Lat POS.Lng BARO.Alt
MAV> graph MODE.ModeNum MODE.Rsn
Filter the ERR messages to subsystem 9 and you have the breach timeline. Overlaying mode against position shows whether the response was the configured action and whether the drone returned successfully.
Why the breach happened — ranked
- Wind drift in Loiter. The drone wasn't holding position precisely enough at the fence edge; gusts pushed it across the polygon line. Verify the wind reading and consider
FENCE_MARGIN— the buffer distance before the fence that the autopilot warns at. - Altitude overshoot on takeoff. The drone climbed past
FENCE_ALT_MAXduring the initial throttle burst. Either lower the throttle expo or raise the ceiling to account for the climb settling. - Operator-uploaded polygon doesn't match the GCS view. The drone is exactly where you wanted it — the polygon you uploaded just doesn't cover it. Re-export the fence to KML and verify visually.
- Home position set wrong. Circle fence uses
FENCE_RADIUSaround home. If the EKF acquired home at the wrong position, the radius is measured from there. Cross-check the home-set MSG line. - Altitude floor triggered during landing.
FENCE_TYPEwith bit 8 set will trigger as you descend. EnableFENCE_AUTOENABLE = 1or 2 so the floor disables during land mode.
Configuring fences that don't trip themselves
FENCE_MARGIN— warning buffer (metres) before actual breach. Useful for operator awareness without triggering action.FENCE_AUTOENABLE— 1 enables the fence on first arming, 2 enables on takeoff and disables before land. The latter avoids floor-fence problems during touchdown.FENCE_ALT_MAX/FENCE_ALT_MIN— ceiling and floor in metres above home altitude.FENCE_RADIUS— circle radius in metres from home.FENCE_RET_ALT— altitude to maintain during fence-triggered RTL. Important if the breach was an altitude one and you don't want to immediately re-breach on the return.
When this isn't really a fence problem
- GPS glitch fakes a breach. The reported
POS.Lat/POS.Lngjumped outside the fence because of a GPS error, not because the drone moved. Cross-checkGPS.HDopandGPS.NSatsat the breach time. See our GPS glitch post. - Wrong home set. If home is on the wrong point because the EKF didn't acquire a 3D fix before arming, the entire fence geometry is offset. Look for the home-set MSG line and confirm the coordinates.
- Polygon altitude not configured. Polygon fences default to no altitude bound; if you wanted a 3D polygon, you need the altitude ceiling bit (1) enabled separately.
When LogHat helps — and when it doesn't
LogHat surfaces the Subsys=9 breach time, draws the breached fence type on the 3D replay, and shows the matching MODE transition with Rsn=10. What we can't tell you is whether the polygon you uploaded was actually the intended boundary — that needs you to verify the coordinates against your operational plan.
About the author
LogHat Engineering Team
The LogHat engineering team — drone-systems engineers who build and operate the LogHat flight analytics platform. Posts in this byline are written and reviewed by team members working on the parsers, analysis engine, and Vector AI that the post describes.
Tagged
Try LogHat
Analyze your flight logs in seconds
Upload a .bin, .tlog, .log, or .ulg file. Get AI crash analysis, 3D replay, and forensic PDF reports instantly.
Try LogHat Free