Safeguard
Supply Chain Security•

How a 3D Printer Is Made: Motion, Mainboard, Firmware and Network

A desktop 3D printer is a frame, motors, a hot end and a mainboard running firmware that reads G-code. How each part is built, and how to secure it.

Safeguard Security Team
50 min read

A desktop 3D printer is made by bolting a frame of extruded aluminium and steel around a motion system of rails, belts, lead screws and stepper motors, then adding a hot end that melts plastic filament and a mainboard whose microcontroller runs open source or vendor firmware. That firmware turns G-code into precisely timed motor pulses and heater commands, and enforces safety checks such as thermal runaway protection. Most printers can also be driven over a network by a host such as OctoPrint or Moonraker, which is useful and, if exposed to the internet, dangerous.

This post goes one level deeper than our builds of a desktop PC and a printed circuit board, and it sits next to our IoT device security fundamentals and the homelab build where a print server often ends up. For the router your printer sits behind, see how a home router is made.

Printer makers do not publish their assembly line yields, burn in times or test rigs. Where an official project document gives a number, we cite it. Where none does, we describe the step without inventing a figure, and the arithmetic in the worked examples is labelled illustrative.

Key takeaways

  • Desktop printers mostly use material extrusion, called FFF or FDM: a motor pushes plastic filament through a hot nozzle while the nozzle moves under computer control. Resin printers cure liquid photopolymer with light, and powder bed machines fuse powder with a laser or a heat source.
  • An FFF printer has six main subsystems: frame, motion system, extruder and hot end, heated bed, mainboard with power supply, and a user interface or network host.
  • Motion layouts differ in how motors map to axes. On a CoreXY machine, the Klipper documentation gives the mapping as stepper A equals X plus Y and stepper B equals X minus Y, so two fixed motors move the head in both directions.
  • The Marlin project describes its firmware as a single self contained application on the mainboard that runs heaters, steppers and sensors in real time. Klipper splits the work: an application processor such as a single board computer plans moves, and the microcontroller executes each step event at the requested time, scheduled with a precision of 25 microseconds or better according to the Klipper docs.
  • Thermal runaway protection is a firmware feature, not a hardware one. Marlin documents three checks on every heater (a heat up watch, a runaway window and MINTEMP or MAXTEMP range checks) and says it is enabled in the default configuration and every example configuration the project ships. Klipper enables heater verification automatically for every configured heater.
  • OctoPrint has made access control mandatory since version 1.5.0 (released 30 November 2020), and its documentation says a device with heaters and stepper motors should not be publicly reachable, even with access control on. Moonraker binds to all IPv4 interfaces on port 7125 by default and trusts no clients unless you list them.
  • The safe pattern is simple: know your firmware version, require logins on the web interface, keep the printer and its host on the local network, and use a VPN for remote access.

Raw material to calibrated printer: the step table

This is the map for the rest of the post. It names the check at each stage rather than a pass rate, because no maker we could find publishes one.

StepInputWhat happensTypical checksOutput
1. Extrusion and cuttingAluminium billetAluminium is pushed through a die to make slotted profile, then cut to length and tappedStraightness, length, square endsFrame members
2. Sheet and machined partsSteel or aluminium sheet, bar stockLaser cut or stamped brackets, machined pulleys, idlers and carriage platesHole position, flatnessBrackets, plates, pulleys
3. Linear motion partsHardened steelGround rods or profiled linear rails with recirculating ball carriages; lead screws rolled or cutDiameter, straightness, carriage preloadRods, rails, lead screws
4. BeltsRubber with glass or steel fibre tension membersMoulded toothed belts cut to lengthPitch, widthGT2 style timing belts
5. MotorsLaminated steel, copper wire, magnetsStator wound, rotor magnetised, bearings pressed, shaft fittedResistance, holding torque, step angleStepper motors
6. Hot end partsAluminium, brass or hardened steel, stainless tubeHeater block machined, nozzle drilled, heat break turned, heater cartridge and thermistor sourcedBore size, thread fit, cartridge resistanceHot end assembly
7. BedAluminium plate, flexible steel sheet, heaterPlate milled or cast, heater bonded, magnetic sheet and build surface appliedFlatness, heater resistance, thermistor readingHeated bed
8. Bare PCBCopper clad laminateImaging, etching, drilling, plating, solder mask (see our PCB post)Electrical test of netsBare mainboard
9. Board assemblyBare PCB, MCU, drivers, MOSFETs, connectorsSolder paste printing, pick and place, reflow, then through hole partsAutomated optical inspection, X ray for hidden joints where usedPopulated mainboard
10. Board programmingPopulated boardBootloader or full firmware written over a debug or USB interfaceProgramming verify, board IDBoard that boots
11. Board functional testProgrammed board in a fixtureEach driver, heater output, fan output and sensor input exercisedPass or fail per channelTested mainboard
12. Final assemblyAll of the above, power supply, displayFrame squared, motion installed, belts tensioned, wiring harness routedSquareness, belt tension, connector seatingAssembled printer
13. Machine firmwareAssembled printerProduction firmware flashed or confirmed, settings stored to EEPROM or config fileFirmware version report (M115 on Marlin)Configured printer
14. Calibration and burn inConfigured printerHoming, bed probing, heater tuning, test printTemperature holds, endstops trigger, first layerCalibrated printer
15. Packing and updatesCalibrated printerBoxed; later firmware and host software updates arrive in the fieldRelease notes, version checksPrinter in service

Steps 10, 13 and 15 are where software enters the machine. The rest of the post follows the parts in roughly that order, then spends its second half on firmware, networking and how to lock both down.

What are the main 3D printing processes?

Additive manufacturing builds a part layer by layer instead of cutting it from a block. Three processes cover nearly all printers you will meet.

Material extrusion (FFF or FDM)

The Marlin documentation describes the process plainly: a motor pushes plastic filament through a hot nozzle that melts and extrudes it while the nozzle moves under computer control, and after minutes or days of thin layers you have a physical object. The two names, Fused Deposition Modeling and Fused Filament Fabrication, describe the same thing; FFF is the term the open source community tends to use. Filament is usually 1.75 mm in diameter. This is the process the rest of this post covers in depth.

Vat photopolymerisation (resin, SLA and MSLA)

A resin printer holds liquid photopolymer in a vat with a transparent film at the bottom. Light cures one thin layer at a time against the film, the build plate lifts, and the next layer cures underneath. Laser based machines (SLA) trace each layer with a steered beam. Masked machines (MSLA) put a monochrome LCD between an ultraviolet LED array and the vat, so the LCD acts as a stencil and a whole layer cures at once. Motion is simpler (often one Z axis), but the machine adds a display driver, an ultraviolet light source and a resin that needs gloves and ventilation.

Powder bed fusion

Powder bed machines spread a thin layer of polymer or metal powder, fuse the cross section with a laser or another heat source, lower the bed and spread again. They are industrial machines and rarely sit on a desk, but the same firmware and network questions apply at a bigger scale.

Comparison: three processes

Material extrusion (FFF)Vat photopolymerisation (MSLA, SLA)Powder bed fusion
FeedstockThermoplastic filamentLiquid photopolymer resinPolymer or metal powder
What forms a layerMolten bead laid by a moving nozzleLight cures resin against a filmLaser or heat source fuses powder
Moving axesUsually X, Y, Z and an extruderOften only ZRecoater, Z and beam steering
Typical heatersHot end and heated bedSometimes a vat heaterBed and chamber heaters, laser
Main hazardsHot parts, fumes, fire from a heater faultUncured resin on skin, fumes, ultraviolet lightFine powder, laser, inert gas, heat
Where firmware sitsMainboard MCU, sometimes a host computerMainboard plus display controllerIndustrial controller and PC

Which parts does a desktop FFF printer contain?

  • Frame. Extruded aluminium profile, folded steel, or a moulded or sheet metal enclosure.
  • Motion system. Linear guides (round rods with bushings, or profiled rails with carriages), toothed belts and pulleys for X and Y, lead screws or belts for Z, and stepper motors.
  • Extruder. A motor and drive gears that grip the filament and push it.
  • Hot end. Heat sink, heat break, heater block, heater cartridge, temperature sensor and nozzle.
  • Heated bed. A flat plate with a heater and a thermistor, usually with a removable build sheet.
  • Electronics. A power supply (commonly 24 V on recent machines), a mainboard with a microcontroller, stepper drivers and MOSFETs, and fans.
  • Sensors. Endstop switches or sensorless homing, a bed probe, and sometimes a filament runout sensor.
  • Interface. A display and knob or touch screen, an SD card or USB slot, and on many printers a Wi-Fi or Ethernet interface or a separate host computer.

How is the motion system built?

A printer is a small robot. Its accuracy comes from three things: a rigid, square frame; guides that let the carriage slide in one direction only; and motors that move a known distance per electrical step.

Frame

Hobby and kit printers often use 20 mm or 30 mm square aluminium extrusions with T slots, joined by corner brackets and screws. Extruded aluminium is cheap, light and easy to adjust. Enclosed consumer printers increasingly use a folded steel or cast chassis, which is stiffer and can be built faster on a line. Either way the assembly check is the same: the frame must be square and flat, or every layer inherits the error.

Linear guides: rods or rails

Two families dominate.

  • Smooth round rods of hardened steel, with linear ball bearings or plastic bushings riding on them. Cheap and forgiving, but they flex over long spans and the bushings wear.
  • Profiled linear rails, where a carriage full of recirculating steel balls runs on a ground steel rail. They are stiffer and more precise but need a flat mounting surface and clean lubrication.

Some budget designs instead run polymer wheels in the slot of an aluminium extrusion. That works, but wheel tension needs periodic adjustment.

Belts and pulleys

X and Y usually move on toothed timing belts. The common hobby belt has a 2 mm tooth pitch and runs on 16 or 20 tooth pulleys. The belt contains glass fibre or steel tension members so it does not stretch under load. Belt tension is set during assembly and is one of the commonest causes of poor print quality when it drifts.

Lead screws

Z usually moves on lead screws, because Z moves slowly and must hold position when the motors are off. A common hobby screw is 8 mm in diameter with an 8 mm lead (the nut travels 8 mm per turn). Some designs use belts for Z as well, so the bed does not drop when power is cut only if the gearing or a brake holds it.

Stepper motors

A hybrid stepper motor has a toothed rotor and a stator with many poles. The common hobby motor has a 1.8 degree step, which is 200 full steps per revolution, in a NEMA 17 frame (a 1.7 inch square faceplate). The stepper driver on the mainboard splits each full step into microsteps by shaping the current in the two coils, which gives smoother motion and finer positioning. The firmware does not know where the motor actually is. It counts the steps it sent, and it finds zero by homing against an endstop switch or by sensing a stall.

Worked example 1: steps per millimetre (illustrative)

Firmware needs to know how many microsteps move an axis by one millimetre.

Belt axis:
  full steps per revolution     = 200    (1.8 degree motor)
  microsteps per full step      = 16
  microsteps per revolution     = 200 * 16 = 3200
  belt travel per revolution    = 20 teeth * 2 mm pitch = 40 mm
  steps per mm                  = 3200 / 40 = 80

Lead screw axis:
  microsteps per revolution     = 3200
  lead (travel per revolution)  = 8 mm
  steps per mm                  = 3200 / 8 = 400

The 80 steps per millimetre figure matches the example in the Marlin introduction, which notes that a typical printer at 80 steps/mm moving at 50 mm/s needs 4,000 pulses per second per axis, and that modern printers often run five to ten times faster. That is why step generation is the most time critical job the firmware has.

Kinematics: Cartesian, CoreXY and delta

Kinematics is the mapping between where you want the nozzle to be and how far each motor must turn. Klipper's configuration reference lists the options it supports, including cartesian, corexy, corexz, delta, polar, rotary delta, winch and hybrid layouts.

  • Cartesian. Each motor drives one axis. The common "bed slinger" moves the bed on Y, the head on X and the gantry on Z. Simple to build and tune, but the moving bed limits speed on tall prints.
  • CoreXY. Two motors fixed to the frame drive a pair of crossed belts. The Klipper kinematics document gives the formulas: stepper A position equals X plus Y, stepper B position equals X minus Y, and Z is independent. Moving both motors the same way moves the head on one axis; moving them in opposite directions moves it on the other. The moving mass is lower, so CoreXY machines can accelerate harder, at the cost of longer belts that must be tensioned equally.
  • Delta. Three vertical towers each carry a carriage, and three pairs of arms hold the effector. Every nozzle move needs all three carriages to move along a computed curve. Deltas are fast and tall, but calibration is harder and errors in arm length show up as dished or tilted layers.

Klipper also describes how moves are shaped: a trapezoid generator gives each move a start speed, a constant acceleration up to a cruise speed, a cruise, and a constant deceleration to the end speed, with look ahead joining moves so the head does not stop at every corner.

Cartesian (bed slinger)CoreXYDelta
Motor to axis mappingOne motor per axisA = X + Y, B = X minus YAll three towers for every move
Moving mass on YWhole bedOnly the head and gantryEffector and arms
Build volume shapeBoxBoxTall cylinder
Assembly difficultyLowestMedium, belt paths and tensionHighest, arm lengths and tower geometry
Typical failureRinging from bed massUnequal belt tension, rackingDimensional distortion from calibration error

How do the hot end and extruder work?

Extruder

The extruder is a stepper motor and a pair of hobbed or geared wheels that grip the filament. A direct drive extruder sits on the print head. A Bowden extruder sits on the frame and pushes filament through a PTFE tube to the head, which lightens the head but makes retraction less precise. Geared extruders reduce motor speed and increase grip.

Hot end, layer by layer

  • Heat sink and fan. Keep the top of the filament path cold so filament does not soften too early.
  • Heat break. A thin walled tube, often stainless steel or titanium, that limits heat flowing upward. If heat creeps up, filament softens in the wrong place and jams.
  • Heater block. An aluminium or copper alloy block that holds the heater and the sensor next to the nozzle.
  • Heater cartridge. A resistive element sealed in a metal tube, usually rated 30 to 60 W at 12 V or 24 V. It must match the supply voltage.
  • Temperature sensor. Most often an NTC thermistor, whose resistance falls as it heats; higher temperature machines use a PT100 or PT1000 platinum sensor or a thermocouple with an amplifier.
  • Nozzle. Brass for general use, hardened steel or other wear resistant tips for abrasive filaments. A 0.4 mm bore is the common default.

The firmware reads the sensor through the microcontroller's analogue to digital converter, compares it with the target, and switches the heater with a MOSFET using pulse width modulation, typically under a PID controller or, in newer Marlin builds, a model predictive controller.

Worked example 2: heater power and current (illustrative)

Heater cartridge rated 40 W at 24 V:
  resistance  R = V^2 / P = 24^2 / 40 = 576 / 40 = 14.4 ohm
  current     I = V / R   = 24 / 14.4 = 1.67 A

Same cartridge mistakenly fitted to a 12 V printer:
  power       P = V^2 / R = 12^2 / 14.4 = 144 / 14.4 = 10 W

A quarter of the expected power is exactly the "weak or wrong heater cartridge" case the Marlin thermal protection page lists as a cause of a "Heating failed" error. The reverse mistake, a 12 V cartridge on 24 V, quadruples the power, which is why matching cartridge voltage is a safety check and not a detail.

Thermal runaway in one paragraph

Thermal runaway is what happens when the controller and reality disagree. The Marlin documentation describes the classic case: the thermistor works its way out of the block and starts reading air, the reading falls, the controller drives the heater harder, and the real block temperature climbs with nothing to stop it. Without a check in firmware, the heater can run at full power until something melts or ignites. We cover the checks in detail below.

What is on the mainboard?

The mainboard is the printer's nervous system. On a typical FFF printer it carries:

  • Microcontroller (MCU). Older boards used 8 bit AVR chips; the Marlin project says it runs on everything from classic 8 bit AVR boards to 32 bit ARM processors, and that Marlin 2.1 supports both families with up to 9 coordinated axes and up to 8 extruders. The MCU holds the firmware in on chip flash.
  • Stepper drivers. One per motor (or per motor pair), either soldered down or on plug in modules. Modern drivers support fine microstepping, quieter current control, and a UART or SPI link so firmware can set current and detect stalls. Marlin has a dedicated documentation section for these configurable drivers.
  • Power MOSFETs. Switch the hot end heater, the bed heater and fans. Beds draw the most current, so some printers use an external MOSFET or solid state relay for the bed.
  • Inputs. Thermistor inputs with pull up resistors, endstop connectors, a probe input, filament sensor inputs.
  • Power stage. Input protection, fuses, a buck regulator from 24 V down to 5 V and 3.3 V.
  • Interfaces. USB (often through a USB to serial chip), an SD card socket, a display connector, and on some boards a Wi-Fi module or a header for a single board computer.
  • Bootloader. A small program at the start of flash that can accept new firmware over USB, serial or from an SD card on boot.

How is a mainboard manufactured and tested?

The bare board follows the process in our PCB post: imaging, etching, drilling, plating and solder mask, then an electrical test of every net. Assembly follows the usual surface mount flow: solder paste is printed through a stencil, a pick and place machine sets the parts, the board passes through a reflow oven, and automated optical inspection looks for missing, shifted or bridged parts. Large connectors and terminal blocks are often through hole parts soldered afterwards.

Then the board is programmed. A test fixture with spring pins contacts the debug or USB interface and writes a bootloader, sometimes the full firmware. A functional test follows: the fixture applies power, toggles each heater and fan output into a load, drives each stepper channel, reads a known resistor on each thermistor input and checks each endstop input. A board that passes gets a serial number or label. Printer makers do not publish their fixture designs or yields; this is the general pattern for small controller boards.

On the finished printer, the firmware is flashed or confirmed again with the machine's own configuration (axis lengths, steps per millimetre, sensor types), because the same board may ship in several printer models.

Comparison: where firmware lives

LayerWhere it runsWhat it doesHow it is updated
BootloaderStart of MCU flashAccepts new firmware over USB, serial or SD cardRarely; usually only with a hardware programmer
Machine firmware (Marlin, Klipper MCU code or vendor firmware)MCU flashReal time step generation, heater control, safety checksSD card, USB, or host driven flash
Display firmwareTouch screen controllerMenus and statusSeparate image on many printers
Host software (OctoPrint, Klipper host, Moonraker, web front end)Single board computer or built in Linux moduleFile handling, web UI, APIs, and for Klipper, motion planningPackage or git updates on the host
Vendor cloud agentPrinter's network moduleConnects to the maker's cloud for remote controlVendor over the air updates

How does G-code drive a print?

From model to G-code

You design or download a 3D model, usually as an STL or 3MF file. A slicer cuts the model into layers, computes the nozzle path for each layer (perimeters, infill, supports), and writes G-code: a text file of commands. The Marlin introduction lists the flow as model, slice, transfer, print, and says Marlin runs G-code sent from a host over USB serial, from a serial controller, or directly from an SD card or USB drive.

What G-code is

The RepRap G-code reference describes the dialect used by printer firmwares and says that codes for print head movement follow the NIST RS274NGC G-code standard, which is why printer firmware can also drive CNC mills and laser engravers. It also notes, frankly, that many firmwares added printer specific codes without coordinating, so sub flavours developed and a code can behave differently from one firmware to another. Always check your firmware's own documentation for a command before relying on it.

A short G-code walkthrough

A start sequence from a slicer often looks like this. Comments after the semicolon explain each line.

M140 S60          ; set bed target to 60 C, do not wait
M104 S210         ; set hot end target to 210 C, do not wait
G28               ; home all axes against endstops
M190 S60          ; wait until the bed reaches 60 C
M109 S210         ; wait until the hot end reaches 210 C
G90               ; absolute positioning for X, Y, Z
M82               ; absolute positioning for the extruder
G92 E0            ; reset the extruder position to zero
G1 Z0.2 F600      ; move to first layer height
G1 X10 Y10 F6000  ; travel to the start of the purge line
G1 X100 E9 F1200  ; extrude a purge line while moving
M106 S255         ; part cooling fan full on (later layers)

The RepRap reference documents G0 and G1 as rapid and linear moves, G28 as move to origin (home), M104 as set extruder temperature, M109 as set extruder temperature and wait, M140 as set bed temperature without waiting, and M115 as get firmware version and capabilities. The Marlin introduction gives two plain language examples: M109 T1 S200 means set heater 1 to 200 degrees, and G0 X100 Y100 F3000 means move to X100 Y100 at 3000 mm per minute.

What the firmware does with each line

In Marlin, most commands execute immediately, while movement commands are queued. The Planner converts moves into straight segments (arcs and curves become many short lines), checks each segment's speed and acceleration against the machine's limits, and smooths the transitions. A high priority stepper interrupt then reads blocks from the planner queue and emits the step pulses. Heater control and the safety checks run alongside, several times a second.

Emergency commands

The RepRap reference describes M112 as a full emergency stop. It also notes that emergency commands in a normal command queue wait their turn, and that recent Marlin versions add an EMERGENCY_PARSER that watches the incoming serial stream so commands such as M108, M112, M410 and M876 act immediately. If your printer runs from a host over USB, that option matters.

How do Marlin and Klipper split the work?

Marlin: everything on the MCU

The Marlin project says it became a standalone project on 12 August 2011, derived from the earlier Sprinter and grbl firmwares, and is licensed under the GPLv3. It runs as one application on the mainboard and handles everything real time: heaters, steppers, sensors, lights, the display and buttons. It can run standalone from an SD card, or you can attach a host like OctoPrint for monitoring.

Marlin is configured at compile time. The Marlin configuration page says options live in two large files, Configuration.h and Configuration_adv.h, as C preprocessor defines; version 2.1.3 and later also accept a single Config.h with just your changes. After flashing new firmware, the docs say to send M502 to load the compiled defaults and M500 to save them to EEPROM, otherwise old stored values stay in effect. The project's GitHub page says Marlin is built preferably with PlatformIO.

Because many commercial printers ship a variant of Marlin, the GitHub page adds a practical note: check with your vendor if you need the source code for your specific machine. The GPL licence is why that request is reasonable.

Klipper: plan on the host, step on the MCU

Klipper takes the opposite approach. Its features page says an application processor, such as a low cost single board computer, calculates printer movements, decides when each stepper should step, compresses those events and sends them to the microcontroller, which executes each event at the requested time. Each event is scheduled with a precision of 25 microseconds or better, and the docs say old 8 bit microcontrollers can reach over 175,000 steps per second while recent ones can reach several million.

The split has practical consequences:

  • Configuration lives in a text file on the host. The Klipper docs say there is no need to reflash the microcontroller to change a setting.
  • Multiple microcontrollers are supported. One can drive the extruder, another the heaters, a third the rest, with clock synchronisation handled by the host.
  • The host is now part of the printer. The Klipper code overview says the host software, Klippy, is mostly Python with C helpers. If the host computer is compromised, the motion planner is compromised.
  • Safety checks are split too. Klipper's configuration reference says the extruder's min_temp and max_temp range check is implemented in the microcontroller code, which shuts down if the measured temperature leaves the range, while heater verification runs on the host.

Comparison: Marlin and Klipper

MarlinKlipper
Where motion is plannedOn the mainboard MCUOn a host computer
Where steps are generatedMCU stepper interruptMCU, from a schedule sent by the host
ConfigurationCompile time C defines, some values in EEPROMText config file on the host
Change a settingEdit, rebuild, reflash (EEPROM values via G-code)Edit the file, restart
Runs without a hostYes, from SD card or USB driveNo, the host is required
LicenceGPLv3GPLv3
Typical network stackSeparate host such as OctoPrint, or vendor moduleMoonraker API plus a web front end, or OctoPrint
Version reportM115Moonraker /printer/info, or the host's git version

How are printers networked and controlled remotely?

There are three common patterns.

OctoPrint on a separate host

OctoPrint is a Python web application that runs on a small computer connected to the printer over USB. It sends G-code line by line, shows temperatures and webcam video, manages files, and supports plugins. Its REST API expects an API key with each request when access control is enabled, and an Application Keys plugin, bundled since version 1.3.10, lets third party apps request a key through an authorisation workflow instead of asking users to paste one.

Klipper with Moonraker and a web front end

Moonraker is a Python web server that exposes a JSON API for Klipper, which web front ends and mobile apps use. The Klipper installation guide names the two main Moonraker based front ends and notes that OctoPrint can also be used with Klipper. Moonraker's configuration docs say the server binds to 0.0.0.0, all IPv4 interfaces, on port 7125 by default. That is fine on a trusted LAN and dangerous anywhere else.

Vendor cloud apps

Many consumer printers ship a Wi-Fi module and a phone app that talks to the maker's cloud. The printer makes an outbound connection to the vendor's service, and the app sends jobs and commands through it, so nothing needs a port forward. That design avoids the classic open port, but moves trust to the vendor's account security, update channel and cloud availability. Some printers offer a LAN only mode. Read the vendor's own documentation for what each mode allows and what data leaves the network.

What can go wrong when a printer is exposed to the internet?

OctoPrint's own guide to safe remote access, written in September 2018, is blunt: "Putting OctoPrint onto the public internet is a terrible idea." It explains why. A printer is a device with motors and heaters, most printers can have their firmware flashed over USB, and once the host computer is compromised an attacker could flash firmware without the safety checks and keep the heater on. The guide also lists sensitive data theft as a lesser risk. It recommends remote access plugins or a VPN rather than port forwarding, and running any reverse proxy or VPN on a separate box from the one connected to the printer.

The current OctoPrint access control documentation says the same thing in fewer words: a physical device with heaters and stepper motors really should not be publicly reachable by everyone with an internet connection, even with access control enabled. It also warns that OctoPrint only embeds the webcam stream, so it cannot protect it; anyone who guesses the webcam URL can watch.

Put together, the risks of an exposed printer host are:

RiskWhat it meansMain control
Physical damage or fireHeaters driven without limits, by command or by reflashed firmwareKeep off the internet; firmware thermal protection; never leave long prints unattended without a plan
Model and job theftG-code and uploaded models are design files, sometimes confidentialAuthentication, network isolation
Webcam exposureLive video of a roomDo not expose the stream; protect it separately
Pivot into the networkThe host is a full Linux computer on your LANSeparate network segment, updates, no default credentials
API key leakageKeys in scripts, slicer settings or shared screenshotsPer app keys, revocation, least privilege groups
Malicious plugins or updatesHost software installs code from the internetInstall from the official repository, keep track of what is installed

NIST's IoT Device Cybersecurity Capability Core Baseline (NISTIR 8259A, May 2020) is a useful checklist for any networked device, printers included. Its six capabilities are device identification, device configuration, data protection, logical access to interfaces, software update and cybersecurity state awareness. A printer host that requires logins, limits which interfaces listen where, and can be updated maps onto most of that list.

Why does thermal runaway protection matter, and how do you confirm it is enabled?

Marlin's three checks

The Marlin thermal protection page opens with the problem: a printer holds a heater at 200 degrees or more a few millimetres from plastic, for hours, often with nobody in the room. It documents three checks on every heater.

  1. Heat up watch. When a new target is set well above the current temperature, Marlin starts a timer. When the timer runs out, the temperature must have risen by at least WATCH_TEMP_INCREASE (2 degrees by default) within WATCH_TEMP_PERIOD (40 seconds by default for hot ends; 60 seconds and 2 degrees for the bed and chamber). If not, the firmware halts with "Heating failed". This catches a heater that has fallen out of the block.
  2. Runaway window. Once a heater reaches its target, the reading must stay within THERMAL_PROTECTION_HYSTERESIS (4 degrees by default) below the target. If it drops out of that band for longer than THERMAL_PROTECTION_PERIOD (40 seconds by default), the firmware halts with "THERMAL RUNAWAY". The bed defaults are 20 seconds and 2 degrees. This is the check that catches a thermistor pulled out of the block.
  3. MINTEMP and MAXTEMP. Every reading is compared with the allowed range regardless of target: 5 to 275 degrees for a hot end by default and 5 to 150 degrees for the bed. An open thermistor wire reads very cold and trips MINTEMP; a short reads very hot and trips MAXTEMP. Marlin also clamps every target to the maximum minus an overshoot margin (15 degrees for hot ends), so with the default 275 degree maximum the highest hot end target is 260.

When any check trips, Marlin prints an error, sets every heater target to zero, switches heater outputs off, stops interrupts and waits. The docs say a killed printer does not respond to G-code and M999 does not recover it; only a reset does. A hardware watchdog (USE_WATCHDOG) resets the board if the temperature code stops refreshing it for about four seconds on AVR and STM32 boards, and a reset turns every heater off.

Worked example 3: how long a fault can run (illustrative)

The Marlin docs advise keeping the total time a heater can run unchecked to a minute or two. Using the documented defaults:

Hot end heat up watch:   must gain 2 C every 40 s
  worst case before a "Heating failed" halt   ~ 40 s

Hot end runaway window:  4 C band, 40 s period
  a thermistor pulled out at temperature reads low,
  stays below (target - 4 C) for 40 s  -> THERMAL RUNAWAY halt

Someone "fixes" nuisance errors with a 300 s period and 30 C band:
  fault can run 300 s at full power before any halt
  that is 7.5 times the default window

The arithmetic is why the docs say that commenting out THERMAL_PROTECTION_HOTENDS or setting a period of several minutes and a hysteresis of tens of degrees "turns the protection off in all but name".

Klipper's checks

Klipper's configuration reference says heater verification is automatically enabled for each configured heater. A [verify_heater] section only changes the defaults: max_error of 120 (a cumulative temperature error counter checked once a second), check_gain_time of 20 seconds for extruders and 60 seconds for the bed, hysteresis of 5 degrees and heating_gain of 2 degrees. Separately, min_temp and max_temp are mandatory for each heater, and the microcontroller code shuts down if the measured temperature leaves that range.

How to confirm protection is on

  • Marlin you build yourself. Search the configuration for the master switches. The Marlin page names them as THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_CHAMBER and THERMAL_PROTECTION_COOLER in Configuration.h, with timings in Configuration_adv.h.
cd ~/src/Marlin
grep -nE '^[[:space:]]*(//)?[[:space:]]*#define[[:space:]]+THERMAL_PROTECTION_(HOTENDS|BED|CHAMBER)' Marlin/Configuration.h
grep -nE '#define[[:space:]]+(THERMAL_PROTECTION_PERIOD|THERMAL_PROTECTION_HYSTERESIS|WATCH_TEMP_PERIOD|WATCH_TEMP_INCREASE|THERMAL_PROTECTION_BED_PERIOD|THERMAL_PROTECTION_BED_HYSTERESIS)' Marlin/Configuration_adv.h
grep -nE '^[[:space:]]*(//)?[[:space:]]*#define[[:space:]]+USE_WATCHDOG' Marlin/Configuration_adv.h

A line starting with // before #define means the option is disabled. All three master switches and the watchdog should be enabled, and the periods should be close to the defaults above.

  • Vendor firmware. You cannot read the compiled configuration, and these are compile time settings, so M503 will not show them. Send M115 to get the firmware name and version, then check the vendor's release notes and, for a Marlin derivative, ask the vendor for the source under the GPL. Do not install community firmware builds of unknown origin to "unlock" features.
  • Klipper. Read your printer.cfg. Look for any [verify_heater] section with unusually large values, and confirm every heater has sensible min_temp and max_temp limits.
  • Behaviour check. Heat the printer with nothing else running and watch the temperature graph in your host. The Marlin docs describe a healthy hot end as climbing steadily, overshooting by a few degrees at most, and then sitting within a degree or two of target with the fan on and off. Do not test protection by pulling a sensor out of a hot block.

Dated timeline: printer firmware and host software

DateEventSource
12 Aug 2011Marlin becomes a standalone project on GitHubMarlin introduction
2013OctoPrint 1.0.0 released, already with a trusted network autologin optionOctoPrint access control docs
24 Aug 2014Date of the commit behind Klipper's earliest tag, v0.1.0Klipper GitHub repository
4 May 2017Marlin 1.1.0 release publishedMarlin GitHub releases
Sep 2018OctoPrint publishes its guide to safe remote access, warning against port forwardingOctoPrint blog
1 Dec 2019Marlin 2.0.0 release publishedMarlin GitHub releases
4 Mar 2020OctoPrint 1.4.0 releasedOctoPrint GitHub releases
May 2020NIST publishes NISTIR 8259A, the IoT device core baselineNIST CSRC
1 Sep 2020Moonraker v0.1.0 release publishedMoonraker GitHub releases
30 Nov 2020OctoPrint 1.5.0 released; access control becomes mandatoryOctoPrint GitHub releases and docs
4 Jun 2022Marlin 2.1 release publishedMarlin GitHub releases
10 Nov 2023Date of the commit behind Klipper tag v0.12.0Klipper GitHub repository
12 Apr 2025Date of the commit behind Klipper tag v0.13.0Klipper GitHub repository
22 Apr 2025OctoPrint 1.11.0 releasedOctoPrint GitHub releases
23 Jun 2026OctoPrint 1.11.8 releasedOctoPrint GitHub releases
12 Oct 2026Marlin 2.1.2.9 published alongside maintenance releases for older branchesMarlin GitHub releases

Release dates move. Check the project pages for the current version before you plan an update.

Step by step: check firmware, require logins, stay off the public internet

These steps assume a printer on a home or office LAN with either OctoPrint or Klipper and Moonraker on a small Linux computer. Replace printer.lan and the addresses with your own.

1. Find the firmware version on the printer

On Marlin or a Marlin derivative, open the terminal in your host (or a serial console) and send:

M115

The Marlin M115 page shows the reply format: a FIRMWARE_NAME field with the version and build date, a SOURCE_CODE_URL, the machine type, the kinematics and, when extended capabilities reporting is enabled, a list of Cap: lines such as EEPROM and EMERGENCY_PARSER. Record the version. Then send M503 to list current settings and save the output with the version, so you can compare after an update.

On Klipper, ask Moonraker. Its printer API documents GET /printer/info, which returns a software_version field such as a git describe string.

curl -s http://printer.lan:7125/printer/info | python3 -m json.tool

If authentication is already on, add your API key as Moonraker's documentation describes, or run the request from a trusted client.

2. Find the host software version

For OctoPrint, GET /api/version returns the API and server versions. Its API documentation says requests need an API key when access control is enabled.

curl -s -H "X-Api-Key: $OCTOPRINT_API_KEY" http://printer.lan/api/version

Compare the result with the project's current release. As of this writing the latest OctoPrint release on GitHub is 1.11.8, published 23 June 2026.

3. Require logins on OctoPrint

OctoPrint 1.5.0 and later always run access control, and the docs say anonymous users get no permissions by default. Your job is to keep it that way.

  1. Sign in as an admin and open Settings, then Access Control.
  2. Check the Guests group. It should grant no permissions. The docs say not to enable any Guest permissions unless you are using a VPN.
  3. Put day to day users in Operator or Read-only Access, not Admins.
  4. Check that autologin is not configured. The docs say not to use it unless you can trust everyone on your local network.
  5. Revoke API keys for apps you no longer use, and prefer per app keys requested through the Application Keys workflow over the global key.

To confirm autologin is off from the host's shell, look at OctoPrint's config.yaml (the path below is common on Linux installs; adjust if yours differs). OctoPrint's config.yaml reference says autologinLocal defaults to false, so it should be absent or false.

grep -n -A4 'autologinLocal' ~/.octoprint/config.yaml || echo "autologin not configured"

4. Require logins on Moonraker

Moonraker's [authorization] section controls access. By default API key authentication is enabled and no clients are trusted. A locked down section looks like this:

# moonraker.conf
[authorization]
enable_api_key: True
force_logins: True
max_login_attempts: 5
trusted_clients:
    192.168.10.0/24
cors_domains:
    http://printer.lan

What each line does, from the Moonraker docs:

  • force_logins: True requires a user login once at least one user exists, overriding trusted_clients. If no users exist, trusted client checks still apply, so create a user first.
  • max_login_attempts locks out an IP after that many consecutive failures; by default there is no limit.
  • trusted_clients grants full API access to listed addresses or ranges. Keep it to the smallest range you need, and prefer IP ranges to hostnames, because the docs warn that a DNS failure makes authentication fail.
  • cors_domains should list your front end's origin. The docs say a bare * is meant for client developers, not production.

Restart Moonraker after editing, then confirm that a request from an untrusted machine is refused.

sudo systemctl restart moonraker
# from a laptop that is NOT in trusted_clients:
curl -s -o /dev/null -w '%{http_code}\n' http://printer.lan:7125/printer/info
# expect an authorization error, not printer data

5. Check what the host is listening on

sudo ss -tlnp | grep -E ':(80|443|5000|7125|8080)\b'

Port 7125 is Moonraker's default. OctoPrint's config.yaml reference says its server binds to 0.0.0.0 on port 5000 by default, and many installs put a web proxy on port 80 or 443 in front of it. Anything listening on 0.0.0.0 is reachable from every network the host is on.

6. Allow only the LAN with a host firewall

On a Debian or Ubuntu based host, the uncomplicated firewall can allow the web ports from your LAN only. Run the allow rules before enabling, so you do not lock yourself out of SSH.

sudo ufw default deny incoming
sudo ufw allow from 192.168.10.0/24 to any port 22 proto tcp
sudo ufw allow from 192.168.10.0/24 to any port 80 proto tcp
sudo ufw allow from 192.168.10.0/24 to any port 7125 proto tcp
sudo ufw enable
sudo ufw status verbose

7. Keep the printer off the public internet

  • Log in to your router and delete any port forward to the printer or its host. Turn off UPnP if you do not need it, because a device can open its own forwards.
  • Put printers and other devices on their own network or VLAN where your router supports it, as described in our home firewall build.
  • For remote access use a VPN into the home network, or one of the remote access plugins listed in OctoPrint's plugin repository, rather than a port forward. OctoPrint's guide recommends a separate box for any VPN or reverse proxy.
  • Treat the webcam stream as its own service. If it is reachable, it is visible.

8. Update host software and record what is installed

OctoPrint, Moonraker, Klipper's host and the web front ends are ordinary software with dependencies. Update them from the project's own channel, and keep a list of installed plugins and their versions. On a Klipper host that uses git checkouts:

for d in ~/klipper ~/moonraker; do echo "$d: $(git -C "$d" describe --tags --always)"; done

9. Flash new MCU firmware safely (Klipper example)

Warning: flashing replaces the firmware on the microcontroller. Flashing the wrong device, or losing power part way, can leave a board that needs a hardware programmer to recover. Stop the print, make sure nothing is heating, and check the device path first.

First confirm the exact device path. The Klipper installation guide says each printer usually has its own unique serial name under /dev/serial/by-id.

ls -l /dev/serial/by-id/*
# Confirm the one entry you expect, for example:
# /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0

If more than one device is listed, unplug the others or identify the right one before continuing. Then build and flash, using the path you just confirmed.

cd ~/klipper/
make menuconfig     # select the MCU and options for your board
make
sudo service klipper stop
make flash FLASH_DEVICE=/dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
sudo service klipper start

The Klipper guide notes that some boards need an initial flash from an SD card instead, and that the board's own documentation describes the method. For Marlin, follow the board's documented method (often copying a firmware file to the SD card and rebooting), then send M502 and M500 as the Marlin docs advise, and M115 to confirm the new version.

Common mistakes

  • Port forwarding the web interface. The OctoPrint guide and access control docs both say not to. Use a VPN or a remote access plugin.
  • Enabling Guest permissions or autologin "just for the LAN". Every device on that LAN, including a compromised one, gets printer control.
  • Leaving Moonraker's trusted_clients wide. A /16 or a whole guest network counts as trusted. Narrow it, create a user and set force_logins.
  • Silencing thermal errors by widening the limits. Marlin's docs say every one of these errors has a physical cause. Fix the sock, the fan duct, the thermistor or the PID tune instead.
  • Installing firmware builds of unknown origin. You lose the ability to know which safety options were compiled in. Build from source or use the vendor's signed or published release.
  • Forgetting M502 and M500 after a Marlin update. Old EEPROM values stay in effect and can mask new defaults.
  • Running the VPN, the reverse proxy and the printer host on one box. OctoPrint's guide suggests separating them so one compromise does not hand over the printer.
  • Exposing the webcam stream. OctoPrint cannot protect it, and it shows your room.
  • Flashing without checking the device path. On a host with several USB serial devices, the wrong board can be overwritten.
  • Treating the host as an appliance. It is a Linux computer with Python packages and plugins, and it needs updates like any other.

FAQ

How is a 3D printer made?

Manufacturers cut and assemble an aluminium or steel frame, fit linear guides, belts, lead screws and stepper motors, add a hot end and heated bed, and wire in a mainboard whose microcontroller is flashed with firmware. The finished machine is configured, calibrated and test printed before packing.

What are the main parts of a 3D printer?

An FFF printer has a frame, a motion system (guides, belts, lead screws, stepper motors), an extruder, a hot end (heater, thermistor, nozzle), a heated bed, a power supply, a mainboard with stepper drivers and MOSFETs, sensors such as endstops and a probe, and a display or network host.

What is the difference between Marlin and Klipper?

Marlin runs everything on the printer's microcontroller and is configured at compile time. Klipper plans motion on a host computer and sends a timed step schedule to the microcontroller, with configuration in a text file on the host. Both are GPLv3 open source projects.

What is CoreXY?

CoreXY is a motion layout where two frame mounted motors drive crossed belts. Klipper's docs give the mapping as stepper A equals X plus Y and stepper B equals X minus Y. It keeps the heavy motors still, so the head can accelerate harder than on a bed slinger.

What is thermal runaway on a 3D printer?

Thermal runaway is a heater running out of control because the controller believes the temperature is lower than it really is, usually because the thermistor has come loose. Firmware checks detect the mismatch and shut every heater down; Marlin halts with a "THERMAL RUNAWAY" message.

How do I know if thermal runaway protection is enabled?

For Marlin you build, check that THERMAL_PROTECTION_HOTENDS and THERMAL_PROTECTION_BED are defined in Configuration.h. For vendor firmware, read the version with M115 and check the vendor's notes or source. Klipper enables heater verification automatically for every configured heater.

Is it safe to expose OctoPrint to the internet?

No. OctoPrint's documentation says a device with heaters and stepper motors should not be publicly reachable, even with access control enabled. Use a VPN or a remote access plugin instead of a port forward.

What port does Moonraker use?

Moonraker's docs give port 7125 as the default, bound to all IPv4 interfaces. Restrict it with a host firewall and the [authorization] settings, and do not forward it from your router.

How do I check my 3D printer's firmware version?

On Marlin based printers, send M115 from a terminal; the reply includes FIRMWARE_NAME with the version and build date. On Klipper, query Moonraker's /printer/info endpoint, which returns software_version.

Can a 3D printer be hacked?

The printer's host computer and network interface can be attacked like any other networked device, and OctoPrint's own guide explains that a compromised host could reflash firmware over USB and disable safety checks. Keeping the printer off the internet and requiring logins removes most of that risk.

Where Safeguard fits, honestly

Safeguard does not analyse printer hardware, scan firmware images, manage devices or generate hardware bills of materials, and it has nothing to say about belts, heaters or kinematics. The honest overlap is the software around the printer. OctoPrint, Moonraker and the Klipper host are Python applications, the web front ends are JavaScript or TypeScript, and print farm dashboards, slicer automation and job queues are usually code your team writes and ships with open source dependencies. If those live in a repository or a container image, Safeguard can scan them (for example safeguard scan --dir . on a checkout, or safeguard scan --image followed by an image name), match components against vulnerability databases, rank findings with reachability analysis, and open fix pull requests when you switch autonomous remediation on. It does not replace the steps above for the printer itself.

A rebuilt print server pulls every Python and JavaScript dependency again, and firmware and host projects for printers are built from hundreds of open source components. The same supply chain hygiene that applies to your web services applies to the code that controls physical machines, which is where the section below comes in.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The first demo is a real Safeguard CLI session asked to fix a lodash CVE: it reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with approval, and pushes nothing. The same flow fits a print farm dashboard or a web front end your team forks and maintains in a JavaScript repository.

Click through it at your own pace, or open it full screen.

The second demo sets up the Safeguard runner on your own machine, approves it with its device code and scans from the terminal. That suits a maker space or lab that keeps printer host configuration, plugins and automation scripts in repositories it prefers to scan locally.

Click through it at your own pace, or open it full screen.

The third demo connects Claude to the Safeguard MCP server with OAuth and shows how you choose which tools Claude can use. A team that asks an assistant about its print farm software can keep that assistant limited to the read and scan tools it actually needs.

Click through it at your own pace, or open it full screen.

To try it on your own repositories, download Safeguard and follow the CLI documentation.

Quick check

A 1.8 degree stepper with 16 microsteps drives a 20 tooth pulley on a 2 mm pitch belt. How many steps per millimetre?
  1. The motor makes 200 full steps per revolution, so 3,200 microsteps. One revolution moves 20 teeth times 2 mm, which is 40 mm. 3,200 divided by 40 is 80 steps per millimetre.
Why does OctoPrint say a printer should not be reachable from the internet even with access control on?

Because it controls heaters and stepper motors. OctoPrint's documentation says such a device should not be publicly reachable by everyone with an internet connection, and its remote access guide explains that a compromised host could reflash firmware without safety checks. Use a VPN or a remote access plugin instead.

Sources

Last reviewed: 24 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.