What Klipper macros can do

How to set up a filament runout sensor in Klipper

One config section turns a switch in the filament path into an automatic pause. The rest is a PAUSE macro that parks the nozzle and keeps the heaters on while you reload.

Published · Last verified

A hand pulling a loose strand of white filament off a spool
Photo: SuperBlobMonster, CC BY-SA 3.0

To add filament runout automation in Klipper, define the sensor as a [filament_switch_sensor] section with its switch_pin. Klipper’s default pause_on_runout: True then pauses the print the moment the sensor stops detecting filament. A PAUSE macro that parks the nozzle handles the stop. Reload, then run RESUME.

[filament_switch_sensor runout]
switch_pin: ^PG12           # placeholder: the input pin your sensor is wired to
pause_on_runout: True       # default; PAUSE runs as soon as runout is detected
event_delay: 3.0            # default; seconds during which new events are ignored
pause_delay: 0.5            # default; seconds between PAUSE and runout_gcode

How do you set up a filament runout sensor in Klipper?

Wire the sensor’s switch to a spare input such as an endstop port, then add a [filament_switch_sensor] section naming that pin in switch_pin, the only required option. Restart Klipper and run QUERY_FILAMENT_SENSOR SENSOR=runout with and without filament loaded. Add ! to the pin if the reading is inverted.

The section name after filament_switch_sensor (here runout) is what every command and macro uses. Klipper’s configuration reference defines the pin prefixes: ^ enables the micro-controller’s pull-up resistor, and ! reverses the polarity (trigger on low instead of high).

The other options, per the configuration reference:

  • runout_gcode runs after runout is detected. With pause_on_runout: True, it runs “after the PAUSE is complete.” Its default is to run nothing.
  • insert_gcode runs when filament goes in. Leaving it out disables insert detection.
  • debounce_delay sets how long, in seconds, the switch must hold one state before Klipper acts. The default is 0. Raise it if a worn switch chatters.
  • pause_on_runout: False with no runout_gcode turns runout detection off.

How to add filament runout automation in Klipper

  1. Add the sensor section. Paste the [filament_switch_sensor runout] block above into printer.cfg with your pin, then save and restart.
  2. Check the reading. Run QUERY_FILAMENT_SENSOR SENSOR=runout with filament loaded, then again with it removed. Klipper reports “filament detected” or “filament not detected”. If both answers come back reversed, add ! before the pin.
  3. Make PAUSE park the nozzle. Klipper’s built-in PAUSE only “pauses the current print” and captures the position, so the hot nozzle stays over the part. Override it with a macro that retracts and moves away, as shown in pause and resume macros. The runout handler sends the PAUSE command, so your macro is the one that runs.
  4. Keep the heaters on while paused. Klipper’s idle timeout defaults to 600 seconds. Once it runs out, the printer runs TURN_OFF_HEATERS and M84, which turns off the motors. Raise the timeout inside your PAUSE macro with SET_IDLE_TIMEOUT TIMEOUT=3600 and restore it in RESUME.
  5. Test it on a real print. Start a small print, then cut the filament above the sensor or lift the switch lever. The print should pause and park. Reload and run RESUME.

If you use the PAUSE, RESUME and CANCEL_PRINT macros that ship with Mainsail or Fluidd (client.cfg), steps 3 and 4 are settings. Copy their _CLIENT_VARIABLE macro into printer.cfg and set variable_idle_timeout. Then set variable_runout_sensor: "filament_switch_sensor runout", and RESUME refuses to continue while the sensor reports no filament.

Klipper macros that use the filament sensor

Klipper’s status reference gives every sensor two values: enabled and filament_detected. Read them as printer["filament_switch_sensor runout"].

Stop a print from starting with no filament by putting this check at the top of the gcode: block in your PRINT_START macro:

    {% set sensor = printer["filament_switch_sensor runout"] %}
    {% if sensor.enabled and not sensor.filament_detected %}
      {action_raise_error("No filament detected. Load filament and start again.")}
    {% endif %}

action_raise_error aborts the current macro “and any calling macros”, so the print stops before anything heats.

To log the runout and confirm a reload, add the templates to the sensor section:

[filament_switch_sensor runout]
switch_pin: ^PG12           # placeholder
runout_gcode:
    {action_respond_info("Filament runout: reload, then run RESUME")}
insert_gcode:
    {action_respond_info("Filament inserted")}

action_respond_info writes to the console without needing a [respond] section.

Why the runout sensor pauses at the wrong time, or not at all

Klipper acts on a runout only while its idle timeout state reads “Printing”, and the source sets that state whenever the toolhead has moves queued. Manual extrusion and unload macros count, not only file prints. Pull filament out during an unload macro and the sensor can pause the printer.

Turn the sensor off around those moves with SET_FILAMENT_SENSOR SENSOR=runout ENABLE=0, and back on with ENABLE=1. Insert events only fire while the printer is not printing.

Other causes:

  • No pause at all: the reading is inverted, so Klipper never sees filament leave. Recheck step 2.
  • Missed second event: a change within event_delay (3 seconds by default) of the last event is “silently ignored.”
  • Random pauses: a bouncing switch or noisy wire. Set debounce_delay, for example 0.1.

Motion sensors and jams

A switch sensor only sees the tail end of the filament. A [filament_motion_sensor] reads an encoder that toggles while filament moves through it. Klipper flags a runout when the extruder pushes detection_length of filament with no toggle, so a jam or tangle trips it too. It takes the same switch_pin, pause_on_runout and G-code options, plus a required extruder and a detection_length that defaults to 7 mm.

[filament_motion_sensor runout]
switch_pin: ^PG12           # placeholder
extruder: extruder
detection_length: 7.0       # mm of filament per expected state change

Sources

  1. Klipper documentation, Configuration reference (accessed October 10, 2026)
  2. Klipper documentation, G-Codes (accessed October 10, 2026)
  3. Klipper documentation, Status reference (accessed October 10, 2026)
  4. Klipper documentation, Command templates (accessed October 10, 2026)
  5. Klipper source, klippy/extras/filament_switch_sensor.py (accessed October 10, 2026)
  6. Klipper source, klippy/extras/idle_timeout.py (accessed October 10, 2026)
  7. Mainsail, mainsail-config client.cfg (accessed October 10, 2026)
  8. Fluidd, fluidd-config client.cfg (accessed October 10, 2026)