3D printer temperature limits explained: nozzle, bed and chamber

Klipper heater verification settings explained

Klipper checks every heater once a second and shuts the printer down if one stops warming the way it should. This page covers the four settings that tune that check, the exact errors it raises and how to loosen it for a slow heater without losing the protection.

Published · Last verified

A hot end heater block with a temperature sensor held in place by Kapton tape
Photo: syvwlch, CC BY 2.0

Klipper’s heater verification is the [verify_heater] check, its thermal runaway protection. It has four settings: max_error (default 120), check_gain_time (20 seconds for extruders, 60 for heater_bed), hysteresis (5 °C) and heating_gain (2 °C). It runs on every heater automatically; writing the section only changes the defaults.

What does verify_heater do in Klipper?

verify_heater is Klipper’s thermal runaway check. It shuts the printer down when a heater is on but its temperature does not behave as expected. Once a second, Klipper compares each heater’s reading to its target: while heating the reading must keep rising, and at temperature it must stay no more than 5 °C below the target.

It works in two phases (verify_heater.py):

  • Heating up. After a new target, the heater must gain heating_gain (2 °C) within check_gain_time. Each time it does, the window restarts and the error counter resets.
  • Holding. Within hysteresis (5 °C) of the target, the counter resets. Below that band, it adds the shortfall every second, and at max_error Klipper shuts down.

Say the extruder target is 250 °C and heating stalls at 230 °C. Once the gain window expires, the counter adds 15 per second (245 °C, the bottom of the in-range band, minus 230 °C) and reaches 120 in about 8 seconds. A hotend holding 250 °C that sags to 235 °C when the part fan ramps up adds 10 per second and trips in 12.

verify_heater settings and defaults

Option Default What it controls
max_error 120 Accumulated shortfall (degree-seconds) before shutdown
check_gain_time 20 s (60 s for heater_bed) Time allowed to gain heating_gain while heating
hysteresis 5 °C Band below target that counts as in range
heating_gain 2 °C Minimum rise required within check_gain_time

Name the section after the heater it tunes:

[verify_heater extruder]
check_gain_time: 30         # seconds; only as long as this heater needs

[verify_heater heater_bed]
check_gain_time: 90

Klipper’s configuration reference says “it is rare to customize” hysteresis or heating_gain, so leave both alone. Only a heater named exactly heater_bed gets 60 seconds. A chamber heater or second bed zone defined as [heater_generic] gets the 20-second default; the chamber heater setup shows a longer one.

What “Heater extruder not heating at expected rate” means

This is the one error verify_heater raises. The console shows:

Heater extruder not heating at expected rate
See the 'verify_heater' section in docs/Config_Reference.md
for the parameters that control this check.

The heater name varies (heater_bed, chamber). To see which phase failed, search klippy.log just before the shutdown. A line like Heater extruder no longer approaching target 250.000 means heating was too slow. No such line means the temperature sagged while holding.

Similar errors from other checks

These come from other checks, so loosening verify_heater does nothing for them:

Message Check Meaning
MCU 'mcu' shutdown: ADC out of range Micro-controller range check The reading left min_temp/max_temp. Analog sensors add a line like Sensor 'extruder' temperature 302.000 not in range 0.000:300.000
Requested temperature (310.0) out of range (0.0:300.0) Target check Target above max_temp. The command is refused; nothing shuts down

Check the sensor and wiring, or see firmware temperature limits before raising max_temp.

How to fix a false verify_heater trip safely

  1. Rule out a real fault first. Check that the sensor and heater cartridge are seated and clamped in the block, the wiring is intact and the part-cooling fan does not blow on the block. A dislodged sensor produces exactly this error.
  2. Re-tune the PID control loop at working temperature. Run PID_CALIBRATE HEATER=extruder TARGET=250 with your own heater and print temperature, then SAVE_CONFIG. Poor tuning causes sag and slow approaches.
  3. Time the slowest rise. Heat to your highest target and watch the temperature graph. Note how long the slowest 2 °C step takes, usually near the top.
  4. Raise only the setting that failed. Slow heating calls for a longer check_gain_time. For sag while holding, fix the cause (silicone sock, fan duct, PID) before touching max_error. If the slowest step took 25 seconds, check_gain_time: 40 is reasonable. A value of 300 is not.
  5. Restart and test. After a shutdown, FIRMWARE_RESTART clears the micro-controller’s error state, which RESTART alone leaves in place. Heat to full temperature and stay with the printer.

After a hotend upgrade

A larger block or lower-wattage cartridge heats more slowly, and every hotend’s rise slows near a high target. Re-run PID_CALIBRATE at the new print temperature first, and lengthen check_gain_time only if the trip persists.

Large beds

A large or thick bed plate on a low-wattage heater can take longer than 60 seconds to gain 2 °C. Measure the rise as in step 3 and size check_gain_time under [verify_heater heater_bed] to match.

Why you should never disable verify_heater

Klipper has no option to turn it off: heaters.py loads verify_heater for every heater. Setting max_error or check_gain_time to a huge value amounts to disabling it, which removes thermal runaway protection.

The other safeguards do not catch a dislodged sensor. The micro-controller shuts down if a reading leaves min_temp/max_temp, and Klipper’s FAQ says the host must confirm an enabled heater “every 3 seconds” or the micro-controller turns all heaters off. A sensor out of its block passes both: it reads a plausible low temperature while the heater runs flat out. Only verify_heater notices the reading is not climbing.

No firmware check can cut power through a switch that has failed on. Voron’s wiring guide warns that cheap solid state relays “may overheat and fail closed causing a heater thermal runaway”.

Sources

  1. Klipper documentation, Configuration reference (accessed October 10, 2026)
  2. Klipper documentation, Frequently asked questions (accessed October 10, 2026)
  3. Klipper documentation, G-Codes (accessed October 10, 2026)
  4. Klipper source, klippy/extras/verify_heater.py (accessed October 10, 2026)
  5. Klipper source, klippy/extras/heaters.py (accessed October 10, 2026)
  6. Klipper source, klippy/extras/error_mcu.py (accessed October 10, 2026)
  7. Klipper source, klippy/extras/adc_temperature.py (accessed October 10, 2026)
  8. Voron Design, Electrical wiring (accessed October 10, 2026)