Voron V2.4 Quad Gantry Leveling — Complete Guide
V2.4 Calibration Gantry
Quad Gantry Leveling (QGL) is the defining calibration feature of the Voron V2.4. Unlike any other consumer 3D printer, the V2.4 uses four independently controlled Z stepper motors — one at each corner of the flying gantry — to keep the print surface perfectly parallel to the toolhead's XY plane. When QGL is working correctly, your first layer is uniform across every corner of a 350mm build plate. When it fails, you get first-layer adhesion problems on one side of the bed, Z banding at specific heights, or in worst cases, the nozzle crashes into the bed. Last updated: May 2025.
This guide covers the complete QGL workflow: why the V2.4's four-motor design requires QGL (and why the Trident's three-motor Z_TILT_ADJUST is different), endstop sensor types and configuration, the printer.cfg setup for QGL, running QGL for the first time with force_move, troubleshooting common failures (endstop trigger issues, Z motor binding, gantry racking), belt synchronization techniques, what to do after QGL (Z offset and bed mesh), and a recommended weekly maintenance schedule.
Why QGL Is Unique to the V2.4
The Voron V2.4 uses a "flying gantry" design where the entire XY gantry moves up and down on four Z leadscrews, each driven by a dedicated stepper motor. This is fundamentally different from:
- Bed-flinger printers (Prusa, Bambu): The bed moves on Z, the gantry is fixed. Leveling means adjusting the bed, not the gantry.
- Voron Trident: The Trident uses three Z motors driving the print bed up and down against a fixed gantry. Its
Z_TILT_ADJUSTlevels the bed, not the gantry. Three motors define a plane perfectly; four motors are over-constrained by nature. - Voron V0.2: A single Z motor with a leadscrew and belt synchronization. No auto-leveling needed — the bed is manually leveled against a fixed gantry.
The V2.4's four Z motors create a critical challenge: the system is over-constrained. If the frame isn't perfectly square, or if belt tension differs between sides, the gantry will "rack" — twist relative to the frame — and bind at certain Z heights. QGL solves this by using the Z endstops as reference points. It moves each Z motor independently until all four endstops trigger simultaneously, ensuring the gantry is parallel to the frame at the endstop position. From there, the assumption is that the leadscrews are consistent enough to maintain parallelism at all heights.
QGL vs Z_TILT_ADJUST (Trident)
While both commands level the print surface against the toolhead, the mechanics differ:
- QGL (V2.4):
QUAD_GANTRY_LEVELuses the Z endstops — typically located on the gantry itself — as reference points. Each Z motor moves independently until the endstop at that corner triggers. QGL assumes the endstops are all at the same height relative to the frame. If one endstop is 0.1mm higher than the others, the gantry will be 0.1mm out of level. QGL runs in one pass typically under 20 seconds. - Z_TILT_ADJUST (Trident): Uses the print bed probe to measure bed tilt at multiple points, then adjusts the three Z motors to tilt the bed until it's parallel to the toolhead. Z_TILT_ADJUST doesn't care about endstop height accuracy — it measures the actual bed position and corrects to make it level. Z_TILT_ADJUST is more forgiving of endstop inaccuracies but requires a functioning probe and takes 2-3 minutes.
The key takeaway: QGL requires very accurate, consistent Z endstop installation. If your V2.4 won't level properly, the first things to check are endstop physical position and wiring, not the QGL configuration itself.
Z Endstop Types and Configuration
The V2.4 needs four Z endstops — one per Z motor. Two approaches are common:
Mechanical Endstops (Standard Voron Design)
The original Voron V2.4 design uses mechanical microswitches mounted on the gantry corners. Each switch is triggered by a horizontal screw (the "endstop screw") that contacts a metal tab on the Z bearing block when the gantry reaches its lowest position.
Configuration in printer.cfg:
[stepper_z]
endstop_pin: ^PC0
position_endstop: 0.0
position_min: -5
endstop_accuracy: 0.010
[stepper_z1]
endstop_pin: ^PC1
position_endstop: 0.0
position_min: -5
[stepper_z2]
endstop_pin: ^PC2
position_endstop: 0.0
position_min: -5
[stepper_z3]
endstop_pin: ^PC3
position_endstop: 0.0
position_min: -5
The position_min: -5 is critical — it allows each Z motor to move 5mm below the nominal
endstop position. QGL needs this negative range because it moves motors downward to find the endstop
trigger point. Without it, QGL will hit the software limit and abort.
Endstop accuracy: Mechanical microswitches typically have 0.01-0.03mm repeatability. This is adequate for QGL (which targets ±0.02mm leveling tolerance), but the switches must be clean and debris-free. A grain of filament dust under the switch lever can shift the trigger point by 0.1mm.
Probe-Based Endstops (Klicky, Unklicky, Voron Tap)
Some V2.4 builds use the print bed probe as a Z endstop, replacing the four mechanical switches with a virtual endstop derived from a single probe measurement. This approach improves accuracy (probes like Voron Tap have 0.005mm repeatability) but adds complexity: you need to probe at four bed locations, calculate offsets, and configure virtual endstops.
For probe-based setups, add [quad_gantry_level] to your config:
[quad_gantry_level]
gantry_corners:
-50, -50
-50, 350
350, -50
350, 350
; Adjust coordinates to match your build plate corners
probe_offsets:
0, 25, 0.5
; Offset is X, Y, Z from probe to nozzle
speed: 200
horizontal_move_z: 10
retry_tolerance: 0.02
max_adjust: 2.0
The gantry_corners define where the gantry is probed. The coordinates should place the
probe at approximately the same XY positions as the four Z leadscrews. The retry_tolerance
of 0.02mm means QGL will repeat the adjustment until all four corners are within 0.02mm of the same
height. max_adjust: 2.0 prevents QGL from making extreme adjustments — if needed movement
exceeds 2mm, it aborts. This protects against a misconfigured system damaging itself.
Configuring QGL in printer.cfg
For the standard mechanical endstop setup, you don't need a [quad_gantry_level] section
at all — Klipper uses the four [stepper_z] sections automatically. However, adding the
explicit section gives you finer control:
[quad_gantry_level]
gantry_corners:
0, 0
0, 300
300, 0
300, 300
; Match your build plate XY bounds
speed: 100
horizontal_move_z: 5
retry_tolerance: 0.02
max_adjust: 2.0
Parameters explained:
gantry_corners: XY coordinates of the Z endstop positions. For mechanical switches, these are the XY positions of the endstop triggers on the gantry. For probe-based, these are the probe XY positions corresponding to each Z motor. List them in the same order as your[stepper_z],[stepper_z1], etc.speed: Speed of Z movement during leveling (mm/min). 100 is slow and safe for initial calibration. After verification, you can increase to 200-300mm/min.horizontal_move_z: Lift height before moving XY between corners. 5mm is safe — high enough to clear any bed clips or PEI sheet edges.retry_tolerance: Acceptable deviation in mm. 0.02mm is the standard for Voron — tighter than most printers need, but achievable with careful endstop setup.max_adjust: Maximum adjustment per motor per retry. If the gantry is 5mm out of level, it would take multiple QGL cycles to correct. 2.0mm prevents aggressive corrections that could bind the gantry.
Running QGL for the First Time — Force_Move Initial Leveling
When you first assemble a V2.4, or after major disassembly, the gantry may be far from level —
sometimes 5-10mm off between corners. QGL's max_adjust of 2mm will abort before
fully correcting this. You need to manually rough-level the gantry first using Klipper's
FORCE_MOVE or manual paper/feeler gauge method.
Initial Rough-Leveling Procedure
- Home the gantry: Run
G28to home all axes. The gantry will move down until each Z endstop triggers. Since the gantry is out of level, some endstops will trigger before others. This is expected. - Check which endstops trigger: Run
QUERY_ENDSTOPfor each Z endstop:QUERY_ENDSTOP NAME=stepper_z QUERY_ENDSTOP NAME=stepper_z1 QUERY_ENDSTOP NAME=stepper_z2 QUERY_ENDSTOP NAME=stepper_z3
Note which endstops show "triggered" and which show "open." The triggered ones are the lowest corners.
- Use FORCE_MOVE to raise low corners: For each motor whose endstop did NOT trigger, move it upward slightly:
FORCE_MOVE STEPPER=stepper_z1 DISTANCE=2 SPEED=5 FORCE_MOVE STEPPER=stepper_z2 DISTANCE=2 SPEED=5 FORCE_MOVE STEPPER=stepper_z3 DISTANCE=2 SPEED=5
The
DISTANCEis a guess — start with 1-2mm. The slow speed (5mm/s) prevents the gantry from binding. - Re-home and check: Run
G28again. Check endstop status. Repeat steps 2-4 until all four endstops trigger on the same G28 cycle. When all four trigger, the gantry is roughly level within the endstop accuracy (±0.03mm for mechanical switches). - Run QGL:
QUAD_GANTRY_LEVEL. It should complete in one pass. If it retries more than 3 times, your gantry still isn't level enough — go back to force_move.
Alternative: Tape/paper method for initial leveling. If you don't want to use
FORCE_MOVE, you can mechanically adjust the gantry using paper feeler gauges:
- Home the gantry with
G28 - Place a piece of standard printer paper under each gantry corner at the Z endstop location
- Manually turn each Z leadscrew coupler (by hand, with power off) until all four pieces of paper have the same drag resistance
- Power on, home, and run QGL
Common QGL Failures and Solutions
Endstop Trigger Failures
Symptom: QGL reports "Endstop not triggered" or the same endstop fails to trigger across multiple attempts.
Solutions:
- Check the endstop wiring — microswitches on Vorons are prone to connector dislodgement during gantry movement
- Verify the endstop screw contacts the switch lever — if the screw is too short, the switch won't trigger. Back out the screw slightly
- Check for debris (filament bits, grease) on the switch lever — clean with isopropyl alcohol and compressed air
- Test the endstop with a multimeter: continuity should break when the switch is pressed
- Inspect the switch mounting — V2.4 printed parts can warp over time in a hot enclosure. If the switch mount has deformed, the switch may not align with the trigger screw
Z Motor Binding at Specific Heights
Symptom: QGL succeeds, but during a print, Z movement becomes rough or noisy at certain heights. The gantry appears to "stick" and then jump.
Solutions:
- Check leadscrew alignment — each Z leadscrew should be perfectly parallel to the Z extrusion. Use a square between the leadscrew and the extrusion. If misaligned, loosen the Z motor mount and reposition
- Verify Z motor coupling — the flexible coupler between the motor and leadscrew should have 2-3mm of vertical gap in the middle. If the coupler is fully compressed or fully extended, the leadscrew length doesn't match the frame height
- Check Z nut blocks — the POM (plastic) nut blocks on the gantry should slide freely on the Z leadscrews. If they bind, the leadscrew has a burr or the nut block is overtightened to the gantry extrusion
- Lubricate leadscrews — apply a small amount of PTFE or lithium grease to each leadscrew and run Z through full range 5-10 times to distribute
Gantry Racking (Twist)
Symptom: After QGL, the gantry appears level at the Z endstop position, but at mid-height or full height, one corner is higher than the others. Measured by moving the gantry to mid-height and measuring from gantry extrusion to top frame on each side.
Solutions:
- Uneven belt tension — measure Z belt tension on all four corners using a tension gauge. The difference should be less than 0.5 N/cm between any two corners
- Check that all four Z belts are the same length — if you replaced one belt and not others, the tension and stretch characteristics will differ
- Inspect Z belt path — a belt rubbing against a printed part or extrusion creates uneven load. Look for shiny spots on the belt indicating rubbing
- Frame squareness — a twisted frame causes the gantry to rack as it moves up. Check frame diagonals (top-left to bottom-right and top-right to bottom-left). They should match within 0.5mm on a 350mm V2.4
- Verify that all four Z bearings (in the Z bearing blocks) are seated properly. A bearing that is cocked in its mount adds friction on one side
Belt Synchronization Techniques
The V2.4 uses GT2 belts to connect the Z motors to the leadscrews. The four Z motors are independent. However, they should all move in sync — when one leadscrew turns, the others must turn at the same rate for the gantry to stay level. Belt synchronization means ensuring that all four belts have the same tension and no slack.
Procedure for Z belt tensioning:
- Home the gantry with
G28so all four endstops are triggered - Mark each belt with a white marker point at the same position relative to the Z motor pulley
- Pluck each belt at the center of its longest span. The frequency should be the same on all four belts. Use a guitar tuner app on your phone
- Target frequency for V2.4 Z belts: 55-70 Hz (an octave below the X/Y belts). If a belt sounds lower, tighten it. If higher, loosen it
- After adjusting one belt, re-check all four — adjusting one affects the tension distribution slightly
- Re-home and re-run QGL after belt adjustments
Belt replacement: Always replace all four Z belts at the same time, even if only one is damaged. Old belts stretch differently from new belts, creating unequal tension that manifests as gantry racking at specific Z heights. Use genuine Gates PowerGrip GT2 belts for consistent stretch characteristics.
After QGL — Z Offset and Bed Mesh
QGL ensures the gantry is parallel to the frame, but it doesn't set your Z offset — the distance between the nozzle and the bed surface. That comes next:
Setting Z Offset
- Run
G28andQUAD_GANTRY_LEVELto prepare the printer - Heat the bed to printing temperature (100°C for ABS) and allow 5 minutes for thermal expansion
- Heat the hotend to printing temperature
- Run
PROBE_CALIBRATEif using a probe, orZ_ENDSTOP_CALIBRATEfor endstop-based Z offset - Use the paper method: place a sheet of paper between nozzle and bed, use the TESTZ command to lower the nozzle, then adjust until the paper has slight drag
- Run
ACCEPTandSAVE_CONFIG
Bed Mesh After QGL
With QGL done and Z offset set, calibrate the bed mesh:
BED_MESH_CALIBRATEwith a 7×7 grid (for 300mm+ beds) or 5×5 grid (for 250mm)- Output the mesh:
BED_MESH_OUTPUT PGP=1to get a visual representation - Ideal mesh deviation after proper QGL: less than 0.15mm across the entire bed. If you see more than 0.3mm deviation, check your bed for warping or your QGL for issues
- Save the profile:
BED_MESH_PROFILE SAVE=default - In your PRINT_START macro, load the mesh:
BED_MESH_PROFILE LOAD=default
Important order: Always run QGL before bed mesh calibration. QGL sets the gantry level relative to the frame. Bed mesh measures the bed surface relative to the gantry. If you mesh first and then QGL, the mesh compensation will be wrong because the gantry moved.
Weekly QGL Maintenance Schedule
QGL is not a set-once-and-forget calibration. The V2.4's gantry is subject to mechanical drift from thermal cycling, belt stretch, and bearing wear. Follow this schedule:
- Before every print: QGL is typically included in your PRINT_START macro, so it runs automatically. This is ideal — each print starts with a freshly leveled gantry. The run takes only 10-20 seconds.
- Weekly: Check Z belt tension with a tension gauge or frequency app. Record the frequency for each belt. If one belt has drifted more than 5 Hz from the others, retension all four.
- Monthly: Run QGL manually and compare the adjustment values Klipper reports. If you see increasing adjustment values over time (e.g., one corner needs 0.5mm more correction each month), you have a developing mechanical issue — check for bearing wear, belt stretch, or leadscrew degradation.
- Every 6 months: Perform the full initial-leveling procedure (force_move or paper method) to verify the gantry hasn't drifted mechanically. Clean all four Z endstops with contact cleaner. Inspect endstop mounts for warping.
- After enclosure temp changes: If you switch from printing PLA (enclosure open or cool) to ABS (enclosure hot at 50-60°C), the frame and gantry will expand differently. Run QGL after the enclosure has stabilized at the new temperature. A temperature change of 20°C can shift the gantry by 0.05-0.10mm on a 350mm V2.4.
Troubleshooting Quick Reference
| Symptom | Likely Cause | Fix |
|---|---|---|
| QGL retries 5+ times | Endstop height mismatch > 0.1mm | Adjust endstop screw positions physically |
| One endstop never triggers | Wiring fault or misaligned switch | Check continuity with multimeter, reseat connector |
| QGL fails with "move out of range" | position_min too high (not -5) | Set position_min: -5 on all Z steppers |
| Good QGL but bad first layer on one side | Bed warped, mesh not loaded, or Z offset wrong | Run bed mesh, verify profile load in PRINT_START |
| Z banding at consistent height interval | Leadscrew binding or bent leadscrew | Roll leadscrew on flat surface, align Z motor mount |
| Gantry "pops" when moving Z | Z bearing block binding on rail | Loosen Z bearing block screws, re-tighten evenly |
| QGL passes but prints show Z-wobble | Worn or bent Z leadscrews | Replace leadscrew — they are consumables after 1000+ hours |