X3DStudios

Why We Validate Every G-code File Before It Prints

X3D Studios··9 min

Every sliced file uploaded to our farm is parsed and scored from 0 to 100 before any printer is allowed to accept it. The scan looks for commands that have no business in a print file — emergency stops, factory resets, endstop overrides, PID rewrites — plus temperatures above what the hardware can survive and files sliced for the wrong machine. A file passes only when nothing has genuinely failed, which means a normal OrcaSlicer or Bambu Studio export scores 100 and goes straight through. Here is exactly what is checked, and why a print farm cannot skip it.

G-code Is a Program, and a Printer Runs It Literally

An STL is a description of a shape. G-code is not. G-code is a list of imperative instructions — move here, extrude this much, set the hotend to this temperature, write this value to memory — and a printer executes them in order without judgement. There is no sandbox. If a line says to raise the nozzle to 340 °C, the heater turns on and stays on.

For a hobbyist that is fine, because the only file on the machine is the one they sliced themselves. A farm is a different problem: machines run unattended overnight, heating to 260 °C in a building with nobody in it, executing files that arrived over the internet from people we have never met. Accepting arbitrary G-code in that setting is not trust, it is an incident with a date on it. The check below is the reason /blog/life-of-a-farm-print-job has a gate between the queue and the machine.

ℹ️This only applies to files you sliced yourself. If you upload an STL, GLB or 3MF, we generate the G-code — but the output is still scanned, because a validator that trusts its own pipeline is a validator with a blind spot.

The Commands We Reject Outright

Nine command patterns are matched against the raw file. Seven of them end the upload; the other two deduct points and get a human involved. The split is not about how obscure the command is, it is about what happens to the machine if it runs.

CommandWhat it does to the printerResultScore
M112Emergency stop — hard-kills the printer mid-jobRejected-30
M211 S0Disables software endstops; the head can drive into the frameRejected-30
M502Factory reset — wipes the machine's calibrationRejected-30
M301Rewrites hotend PID values — thermal runaway riskRejected-30
M304Rewrites bed PID values — thermal runaway riskRejected-30
M851Moves the Z-probe offset — nozzle crash into the bedRejected-30
G28.1Redefines the home position and desyncs the coordinatesRejected-30
M500Writes settings to EEPROM — unusual in a print fileFlagged-10
M999Restarts the controller boardFlagged-10

The two flagged commands are worth explaining, because they are the interesting case. Neither M500 nor M999 is dangerous on its own. Both are simply wrong for a print file — a slicer has no reason to write EEPROM or reboot a board mid-job — so their presence usually means the file went through a non-standard post-processor. That is not a reason to refuse the job, but it is a good reason for somebody to read the start G-code before it runs on a machine worth more than the order.

Scorecard of nine G-code safety checks with their point deductions: M112, M211 S0, M502, M301 and M304, M851 and G28.1 each cost 30 points and reject the file, a wrong printer model costs 50, a nozzle above 320 Celsius costs 30, an empty file costs 40, and M500 or M999 cost 10 as flags
The deductions are not decoration — they are what the validator actually subtracts.

Two Temperature Ceilings, Not One

Temperature is where a naive validator gets annoying. Cap everything at PLA's limits and half of the legitimate ABS and ASA work on the farm gets blocked; cap nothing and a typo in a custom start script cooks a hotend. So there are two ceilings, and they behave differently.

CeilingNozzleBedWhat crossing it does
Hardware absolute320 °C130 °CHard fail — the file is rejected
PLA typical max260 °C75 °CWarning only — job still prints
PETG typical max280 °C90 °CWarning only — job still prints
ABS typical max290 °C115 °CWarning only — job still prints

The reasoning is that a material mismatch is a quality problem, not a safety one. A file declaring PLA but commanding 275 °C is probably mislabelled rather than lethal, and it earns a five-point deduction and a note rather than a refusal. A file commanding 340 °C is dangerous whatever the material says, so it costs thirty points and stops there.

Both the header values and the body of the file are checked. It is not enough to read the filament profile at the top, because temperature can be changed anywhere: every M104, M109, M140 and M190 in the file is collected and the highest value found is the one that gets judged. A file that starts politely at 215 °C and ramps to 340 °C on layer 200 fails on the 340.

The File Has to Match the Machine It Is Going To

The heaviest single deduction in the whole system is not a dangerous command. It is a fifty-point failure for a file sliced for the wrong Bambu model, and it exists for a purely practical reason: the printer firmware will refuse the file anyway. Catching it at upload turns a cryptic error code discovered after handoff into a sentence that tells you what to do.

Doing that comparison takes a little care, because the slicer and the fleet database do not name machines the same way. OrcaSlicer embeds something verbose like Bambu Lab H2S 0.4 nozzle; the fleet record says Bambu Lab H2S. Both are normalised down to a short model key before they are compared, so a nozzle size or a missing space never reads as a mismatch. Our fleet is H2S and P2S, and the two are genuinely different targets: the P2S is a 256 mm-class bed, while the H2S is the machine behind our published 340 × 320 × 340 mm build volume.

If you are slicing your own files, this is the check most worth pre-empting, and it costs you nothing to get right. /blog/how-to-export-sliced-file-bambu-studio walks through the export, and the short version is: pick the printer profile that matches the machine your job will run on, then export .gcode or .gcode.3mf.

Warnings Are Not Failures

Two-column comparison: the blocking column lists M112, M502 and M211 S0, PID rewrites, Z-offset and home changes, nozzle above 320 Celsius or bed above 130, a mismatched printer model and files under 10 lines; the warning column lists material temperature mismatches, M500 and M999, a footprint near the bed edge, a missing layer count and prints over 72 hours
Safe means zero failed checks. The score is a summary; the failure list is the gate.

This is the design decision that keeps the validator usable. A file is safe if and only if no check failed — the score is a report, not the gate. A job can arrive with 92 points and print happily, because those eight points came from a temperature slightly above the material's typical maximum and a footprint estimate that grazed the bed edge. Neither of those will hurt anyone.

Getting that backwards is how safety systems get switched off. A gate that blocks on a score threshold blocks perfectly good slices, an operator overrides it three times in a week, and by the second month it is off. Blocking only on genuine failures means the block means something, and nobody has a reason to route around it.

Why Some Checks Are Deliberately Tolerant

Two checks are looser than they look, and both for the same reason: the measurement is noisier than the thing being measured.

  • XY footprint is estimated from the early moves in the file, and those moves include full-bed calibration, purge and wipe travel — so the estimate is routinely wider than the part. A small overage is a three-point note; only a gross overage past 25% raises a real warning, and even that is advisory, because a properly sliced file fits its own plate by construction.
  • Z height is read from real print moves and is far more reliable, but Bambu's end G-code parks the bed near maximum Z, which inflates the measured height. Twenty millimetres of headroom is allowed so a normal print never trips it.
  • Estimated print time over 72 hours is a warning, not a block. Some jobs genuinely take three days; the flag exists so a human notices before a machine is committed for that long.
  • A missing layer count costs five points and warns, because it usually means the file was not fully sliced — a real problem, but one the operator should see rather than one the software should decide alone.

The exception is the sanity floor. A file with fewer than ten lines of G-code is empty or corrupt, costs forty points, and fails. There is no interpretation to do — nothing is going to print.

What Happens When a File Is Rejected

Nothing dramatic. The job stops at validation instead of moving to the queue, the failed checks are shown with the specific reason attached, and no printer is ever offered the file. From there it is usually a re-slice: change the printer profile, drop the custom start G-code your post-processor injected, or fix the temperature override. Re-upload and the job continues from where it stopped.

If you would rather not deal with slicer settings at all, upload the mesh instead. STL, GLB and 3MF go through our own OrcaSlicer pipeline, which means the G-code is generated with a profile that matches the machine and the material, and the quote comes from that same slice at $0.12 per gram all-in for PLA, $1.00 minimum per part. /blog/slicing-mistakes-that-ruin-prints covers the settings most likely to cost you a reprint if you do slice it yourself.

The Score Does Not Stop at the Gate

One detail people miss: the safety score keeps working after the print starts. When a job finishes, the plate is evaluated for automatic ejection — cooling the bed and pushing the plate off so the next job can start unattended — and one of the six conditions for attempting that is a G-code safety score above 70. The others are physical: PLA only, under 100 mm tall, 20 to 150 cm² of footprint, no taller than three times its width, and a bed at 75 °C or below.

That coupling is intentional. A file the validator was unsure about does not get to be the one that runs the robotic step with nobody watching. It prints, and then a person collects it. Everything else in /blog/is-3d-printing-safe follows the same principle: automation is granted to the cases you have actually verified.

💡Submitting jobs programmatically? The same validation runs on API-submitted files, and the check results come back with the reason attached rather than a generic rejection. The endpoints are documented at /api-docs.

FAQ

Will my normal sliced file pass validation?

Almost certainly. A stock OrcaSlicer or Bambu Studio export for the correct printer contains none of the nine flagged commands, keeps temperatures inside the material profile, and declares its layer count — that is a score of 100. The common real-world failure is not a dangerous command, it is a file sliced for a different printer model.

Why would a G-code file contain an emergency stop command?

Usually by accident. M112 turns up in test files, in snippets copied from forum posts into custom start G-code, and in output from post-processing scripts written for a different machine. Malice is rare; a copy-paste from someone else's start block is not. Either way the printer cannot tell the difference, which is the point.

Can I upload G-code instead of an STL?

Yes. We accept .gcode and .gcode.3mf up to 40 MB, alongside STL, GLB and 3MF meshes up to 100 MB. OBJ is not accepted. When you send sliced G-code we price the slicer's own measured numbers rather than re-slicing, so what you planned is what gets made — provided it passes the safety scan first.

Does validation slow my order down?

No. The scan is a parse of a file that is already in memory and finishes in the same moment the price appears. On a normal order the entire validating state lasts seconds, and the real wait is the queue in front of a free printer.

Ready to get started?

Upload a 3D model for instant pricing, or generate one with AI.