Two nozzles print one clean part only when the printer knows where the second nozzle sits relative to the first. Bambu Lab's dual-nozzle machines measure that with a sensor; on Klipper and Marlin you measure it from a test print and enter it yourself.
On a Bambu Lab H2D or X2D, open Settings > Calibration on the printer screen and run Nozzle Offset Calibration: the printer measures both nozzles itself. On a Klipper or Marlin printer, print a test with both nozzles and measure how far the second nozzle’s lines miss the first’s. Enter that as the second tool’s X, Y and Z offset.
How do you calibrate the nozzle offset on a dual nozzle printer?
Bambu Lab’s H2D and X2D calibrate it themselves: start Nozzle Offset Calibration from the screen, or leave it on Auto when sending a print. On Klipper, put each tool’s offset in its T0/T1 macro with SET_GCODE_OFFSET. On Marlin, set it with M218 T1 and save with M500. In every case, level both nozzle tips to the same height first.
The offset has two parts. XY is how far the second nozzle sits from the first across the bed. Z is how much higher or lower its tip sits. A wrong XY value shifts everything the second nozzle prints sideways. A wrong Z value makes it print too high or scrape the part.
How to run nozzle offset calibration on a Bambu Lab H2D or X2D
- Open the calibration menu. On the printer screen, go to Settings > Calibration and select Nozzle Offset Calibration.
- Let it measure. Both nozzles touch the heatbed in turn to measure the Z difference. Then each nozzle finds the center of the offset sensor behind the bed to measure XY.
- Keep the per-print check on. When you send a print, leave the Nozzle offset calibration option on Auto. That runs a quick check before the print and falls back to a full calibration if the check fails or finds a large offset.
- Use high precision if lines still miss. On the H2D, run High-Precision Nozzle Offset Calibration from the same menu. It needs one dark and one light filament.
Bambu Lab gives the sensor’s XY positioning accuracy as about 15 to 20 µm. For Z, the two nozzles are designed to sit 5 mm apart in height, and the bed rises or falls 5 mm at each nozzle switch. Assembly and nozzle tolerances keep the real gap from being exactly 5 mm, so the measured difference is applied to the bed height during the print.
The send-print option has three settings:
| Setting |
What happens before the print |
| Auto |
Quick XY check; a full calibration runs if the check fails or the offset is too large |
| On |
Full calibration; if the sensor signal is weak, the screen’s Nozzle Offset Calibration runs, then an error if it is still weak |
| Off |
No check; uses the stored values |
High-precision calibration prints a test model with the two filaments, one loaded for each nozzle through the AMS (Bambu’s automatic material system) or the external spools. The toolhead camera on the right side photographs it and finds the centers of the lines each nozzle drew, which should sit 7 mm apart. The difference from 7 mm is the XY offset. Because it measures the printed lines themselves, Bambu Lab expects it to beat the sensor’s accuracy.
Under current firmware, set the send-print Nozzle offset calibration option to Off to print with the high-precision values, or the sensor check runs again. On the H2C, high precision covers only the hotends on the toolhead, not the hotend rack.
The H2C runs the same sensor calibration on the toolhead hotend and on every hotend in its induction rack, so it takes longer with more hotends installed. For the machines themselves, see the H2D’s dual nozzle system and the H2D compared with the X2D.
When should you rerun nozzle offset calibration?
Rerun it after a nozzle or hotend swap and whenever a two-nozzle print shows a sideways step where the nozzles switch. Bambu Lab recommends recalibrating after changing any hardware component, and specifically after a visible layer shift between nozzles. A hotend that is not clipped in fully moves the tip, so check the clip first (how the H2D’s two nozzle sizes work covers swaps).
How to calibrate nozzle offset in Klipper or Marlin
- Level the two tips. With both hotends cold, check each nozzle with the same feeler gauge or sheet of paper at the same spot. Adjust the second hotend until the drag matches. Leave the bed alone.
- Enter the nominal spacing. Measure the nozzle-to-nozzle distance with calipers or take it from the toolhead design. Set it as the second tool’s starting offset.
- Print an alignment test. Print a two-nozzle test, a few layers high, with contrasting colors on each nozzle.
- Measure the error. Read how far the second nozzle’s lines land from the first’s, in X and in Y (the next section shows how).
- Correct the offset. Add the error to the second tool’s offset, keeping the sign convention of your firmware.
- Reprint until it matches. Print the test again and repeat until the lines meet. Then print a two-color part to confirm.
Klipper has no stored hotend offset. Each T0/T1 macro sets it with SET_GCODE_OFFSET and switches extruders with ACTIVATE_EXTRUDER. Klipper’s own two-extruder sample config does the same. The values below are placeholders for a second nozzle about 20 mm to the right of the first:
[gcode_macro T0]
gcode:
SET_GCODE_OFFSET X=0 Y=0 Z=0 MOVE=1
ACTIVATE_EXTRUDER EXTRUDER=extruder
[gcode_macro T1]
gcode:
SET_GCODE_OFFSET X=-20.15 Y=0.08 Z=0.10 MOVE=1
ACTIVATE_EXTRUDER EXTRUDER=extruder1
Klipper adds the offset to every later G-code move. A second nozzle 20 mm to the right of the first therefore needs a negative X offset, so the carriage moves left to put that nozzle where the G-code asked. Positive Z lifts the second nozzle.
To test a correction at the console before editing the config, use SET_GCODE_OFFSET X_ADJUST=<error>. X= replaces the offset; X_ADJUST= adds to it. Z= replaces any Z baby-step made in Mainsail or Fluidd at every tool change. If you baby-step during prints, set only X and Y in the macros and fix the height difference mechanically. Adding Klipper macros covers where these go.
Marlin: M218 and M500
Marlin stores the offset as the second hotend’s distance from hotend 0, the opposite sign from Klipper: a nozzle 20 mm to the right is X20. Send:
M218 T1 X20.15 Y-0.08
M500
M503 prints the current values. M500 saves them to EEPROM (the board’s settings memory) and needs EEPROM_SETTINGS enabled in the firmware. Without it, put the values in HOTEND_OFFSET_X, HOTEND_OFFSET_Y and HOTEND_OFFSET_Z in Configuration.h and reflash.
Marlin’s documentation lists the Z hotend offset as available only with DUAL_X_CARRIAGE or SWITCHING_NOZZLE. On a fixed two-nozzle carriage, fix height differences mechanically.
How to read an XY nozzle offset calibration print
There are two common test layouts.
- Vernier grid. Each nozzle prints a row of numbered lines at slightly different spacing. Find the pair of lines that line up best; its number times the step size is the correction. UltiMaker printers have this test built in, with 73 µm per step and the 0 line in the middle. When two neighbors line up equally well, UltiMaker allows a half step such as +1.5.
- Nested squares. The first nozzle prints a single-wall square; the second prints a larger one around it with an equal designed gap on every side. Measure the left and right gaps with calipers. The second nozzle’s X error is half of (right gap minus left gap). Do the same for Y with the front and back gaps.
Worked example: the left gap measures 1.3 mm and the right 0.7 mm. The second nozzle printed (0.7 - 1.3) / 2 = -0.3 mm, so it landed 0.3 mm too far left. Correct it like this:
| Firmware |
Second nozzle printed 0.3 mm too far left |
Second nozzle printed 0.3 mm too far right |
| Klipper |
SET_GCODE_OFFSET X_ADJUST=0.3 |
SET_GCODE_OFFSET X_ADJUST=-0.3 |
| Marlin |
lower the M218 T1 X value by 0.3 |
raise the M218 T1 X value by 0.3 |
Jog the axes once to confirm which direction is +X and +Y on your printer before applying a sign.
How do you level two nozzles to the same height?
Check both tips cold with the same gauge at the same bed position. Leave the bed alone and move the second hotend to match the first. Raise3D’s Pro2 procedure follows this order: set the left nozzle’s height first, then loosen the right hotend’s retaining screw and slide it until it touches the gauge. Raise3D warns that adjusting the bed afterwards puts the left nozzle out again.
On printers without an adjustable hotend, measure the remaining difference and enter it as the second tool’s Z offset in Klipper. If the second nozzle sits lower and the firmware cannot lift it, it drags through the first nozzle’s layers, so a mechanical fix comes first.
What does nozzle misalignment look like?
| What you see |
Likely cause |
What to check |
| A sideways step at every color or material change |
XY offset wrong |
Rerun calibration, or measure a test print and correct X/Y |
| Gaps or overlaps where two materials meet |
Small XY error |
Vernier or nested-square test; UltiMaker notes single-nozzle prints are unaffected |
| Soluble supports that do not touch the part |
XY or Z error on the support nozzle |
Both offsets; see PVA supports on a dual nozzle printer |
| Second nozzle’s layers squashed, or the nozzle scrapes the part |
Second tip too low |
Tip leveling, then Z offset |
| Second nozzle’s lines rounded and loose |
Second tip too high |
Z offset |
| Offset changes after a nozzle swap |
Hotend seated differently |
Hotend clip and seating, then recalibrate |
| Blobs and strings from the idle nozzle |
Ooze, not offset |
Dual nozzle ooze |
Why does Bambu nozzle offset calibration fail?
Bambu Lab lists these causes for a failed sensor calibration:
- No sensor signal: the sensor is damaged, missing or unplugged (Bambu’s HMS error page 0300-2700-0001-0004 covers the connector).
- Third-party nozzles: non-magnetic nozzles such as silicon carbide do not register, and A1-series hotends are not recommended.
- A loose hotend: the hotend must sit flush in the heater base with its locking clip fastened. A badly seated left hotend raises error HMS_0300-2600-0001-000B.
- Old firmware: a firmware bug; Bambu Lab points to version 01.01.02.08 or later.
High-precision calibration fails for different reasons:
- the two filaments are too close in color for the camera
- the top lines of the test model did not print cleanly (check adhesion and clogs)
- the chamber lights are off
- the toolhead camera is dirty, blocked or out of place
- the nozzle is fitted skew