Skip to content

Configuration Examples

Titus Meyer edited this page Jun 4, 2026 · 1 revision

Configuration Examples

This page provides short templates for common setups. Treat them as starting points, not complete printer configurations.

Replace every placeholder with values from your printer, then verify the behavior with Testing and Tuning.

Warning: Do not copy coordinates from another printer. Wrong endstop, switch, or bed positions can move the nozzle into unsafe areas.

Minimal Z Calibration

Use this when [safe_z_home] provides the nozzle endstop position and [bed_mesh] provides zero_reference_position.

[z_calibration]
switch_xy_offsets:    <X,Y offset from nozzle position to probe switch body>
switch_offset:        <positive switch trigger offset>
start_gcode:          ATTACH_PROBE
end_gcode:            DOCK_PROBE

If no bed mesh zero reference is configured, add bed_xy_position.

bed_xy_position:      <X,Y bed position to probe>

Attach Probe After Nozzle Probing

Use before_switch_gcode when the probe should be attached only after the nozzle has touched the Z endstop.

[z_calibration]
switch_xy_offsets:    <X,Y offset from nozzle position to probe switch body>
bed_xy_position:      <X,Y bed position to probe>
switch_offset:        <positive switch trigger offset>
before_switch_gcode:  ATTACH_PROBE
end_gcode:            DOCK_PROBE

Bed Mesh Zero Reference

For new bed mesh configurations, prefer zero_reference_position. If bed_xy_position is omitted, CALIBRATE_Z uses this mesh position.

[bed_mesh]
zero_reference_position: <X,Y mesh reference position>

[z_calibration]
switch_xy_offsets:       <X,Y offset from nozzle position to probe switch body>
switch_offset:           <positive switch trigger offset>
start_gcode:             ATTACH_PROBE
end_gcode:               DOCK_PROBE

Legacy: relative_reference_index is deprecated in Klipper. The plugin can still read it when Klipper exposes it, but new configurations should use zero_reference_position.

Current Option Names

Current refactored releases use these option names:

[z_calibration]
offset_margins:  -1.0,1.0
safe_z_height:   20
#offset_gcode:   <optional custom offset application G-code>
#error_gcode:    <optional error handling G-code>

Remove the old max_deviation and clearance options from [z_calibration].

Warning: Do not leave removed options in the configuration as active legacy settings. From version 1.2.0 on, the implementation no longer reads them.

Explicit Positions

Use explicit positions when [safe_z_home] or [bed_mesh] cannot provide the needed coordinates.

[z_calibration]
nozzle_xy_position:   <X,Y position where the nozzle touches the Z endstop>
switch_xy_position:   <X,Y position where the probe switch body touches the Z endstop>
bed_xy_position:      <X,Y bed position to probe>
switch_offset:        <positive switch trigger offset>
start_gcode:          ATTACH_PROBE
end_gcode:            DOCK_PROBE

switch_xy_offsets can be used instead of switch_xy_position when the switch body position is easier to express as an offset from the nozzle position.

Custom offset_gcode

By default, CALIBRATE_Z resets the old G-code Z offset and applies the calculated value with SET_GCODE_OFFSET. Configure offset_gcode only when another system needs to apply the result differently. The main use case is a multiple-toolhead or toolchanger printer where the correction must be applied to tool-specific state.

The calculated offset is available as params.Z.

[z_calibration]
switch_xy_offsets:    <X,Y offset from nozzle position to probe switch body>
bed_xy_position:      <X,Y bed position to probe>
switch_offset:        <positive switch trigger offset>
start_gcode:          ATTACH_PROBE
end_gcode:            DOCK_PROBE
offset_gcode:
    SET_GCODE_OFFSET Z=0.0
    SET_GCODE_OFFSET Z_ADJUST={params.Z|float}

This example matches the built-in behavior. It is useful as a starting point before replacing the offset application with printer-specific commands.

Passing Hook Values to Macros

offset_gcode and error_gcode are G-code templates. If they call another macro, pass the received hook parameter to that macro explicitly.

[z_calibration]
offset_gcode:
    _APPLY_Z_CALIBRATION_OFFSET Z={params.Z}
error_gcode:
    _Z_CALIBRATION_ERROR ERROR="{params.ERROR}"

[gcode_macro _APPLY_Z_CALIBRATION_OFFSET]
gcode:
    {% set offset = params.Z|float %}
    SET_GCODE_OFFSET Z=0.0
    SET_GCODE_OFFSET Z_ADJUST={offset}

[gcode_macro _Z_CALIBRATION_ERROR]
gcode:
    RESPOND TYPE=error MSG="Z calibration failed: {params.ERROR}"

Do not use only _APPLY_Z_CALIBRATION_OFFSET as the offset_gcode value unless that macro does not need the calculated offset. Without Z={params.Z}, the called macro has no params.Z.

error_gcode Buzzer

Use error_gcode when the printer should react to a failed CALIBRATE_Z. One common use is sounding an internal buzzer, then printing the error message.

[z_calibration]
error_gcode:
    _Z_CALIBRATION_ERROR ERROR="{params.ERROR}"

[gcode_macro _Z_CALIBRATION_ERROR]
gcode:
    M300 S880 P300
    M300 S440 P300
    RESPOND TYPE=error MSG="Z calibration failed: {params.ERROR}"

M300 is a common buzzer macro name, but it is not guaranteed to exist on every Klipper configuration. Replace it with the buzzer or notification macro used by your printer.

Kinematic Position offset_gcode

Some toolchanger or custom kinematic setups may need the calibration result to change the toolhead kinematic position instead of Klipper's G-code offset.

Warning: Klipper documents SET_KINEMATIC_POSITION as a low-level position-tracking command. Use this only when the printer architecture requires it and verify the behavior with slow moves before printing.

[z_calibration]
switch_xy_offsets:    <X,Y offset from nozzle position to probe switch body>
bed_xy_position:      <X,Y bed position to probe>
switch_offset:        <positive switch trigger offset>
start_gcode:          ATTACH_PROBE
end_gcode:            DOCK_PROBE
offset_gcode:
    {% set offset = params.Z|float %}
    {% set current_z = printer.toolhead.position.z|float %}
    SET_KINEMATIC_POSITION SET_HOMED= Z={current_z - offset}

The empty SET_HOMED= is intentional. Without it, Klipper's command default changes the homed-axis state.

Multiple Klipper Instances

The installer can check and restart numbered Klipper services:

./klipper_z_calibration/install.sh -n 2

The installer expects services named klipper-1, klipper-2, and so on.

Note: The Moonraker update manager block written by the installer still uses managed_services: klipper. If your Moonraker setup uses numbered or custom service names, adjust that line in moonraker.conf.

Next Step

After adapting a template, continue with Testing and Tuning.

Clone this wiki locally