Troubleshooting a Node: LEDs, USB, Printing

It will not come up, will not print, or keeps restarting. Read the LED, read the status, work the USB recovery ladder — and know the one fault it cannot fix.

Published 2026-09-09 · All documentation

Start with the light on the box. It is the only diagnostic that works when nothing else does — no network, no page to load, no paper — and it narrows the problem to one of six states before you touch anything.

Read the LED first

PatternStateWhat it means
Fast blinkBootingComing up. If it never leaves this, see the crash record below
Medium blinkConnectingJoining Wi-Fi
Slow heartbeatOnlineServing on the LAN. Near-dark most of the time — this is the healthy one
Rapid double-blinkErrorA fault: paper out, or no network
Slow double-winkSetupWaiting in setup mode for somebody to join it to a network. On a unit with no printer this is the only sign the node is sitting in the portal, so it is a long dark pause and gentle winks — deliberately unlike the error pattern
Rapid continuous flutterUpdatingA firmware image is being written to flash. Do not pull the cable
Flowchart of the six boot stages against the LED pattern shown at each, and what the boot log retains after a panic.
Read this standing in front of a node that will not come up. The boot record is kept in non-volatile storage, so it survives panics, power cycles and reflashes — a build that broke the boot can be flashed over and still interrogated afterwards.

Then read the status

Everything below assumes you can reach the node. If you cannot, find it with a tap of the B button — it announces itself as a Wi-Fi network whose name carries its id and current address, and says no-network when it has none — or over mDNS at proxynodes-<id>.local. Setup covers both.

curl -s http://<node-ip>/status

That one response carries the peripheral bindings, the USB diagnostics, the recovery state, the scale, the camera, the webhook delivery health and every printer. It is also what to paste into support — it is most of the diagnosis.

The distinction to read for is absence. Status separates a peripheral that was never plugged in, one refused for want of a USB channel, one seen and gone with an age attached, and one bound and silent. Those are four different faults with four different fixes, and a surface that collapsed them would send you to the wrong one.

The printer

SymptomLikely causeFix
No device event at allThe cable’s ID pin, or no 5 V on the printer sideDoes the printer enumerate on a laptop? The board does not source 5 V — use a cable arrangement with a powered leg
Enumerates, but the log says no usable printer interfaceA vendor-class device with the fallback offTurn on vendor-class acceptance in config, then replug
Prints, then the node rebootsBrownout under head currentGive the node its own supply. Do not power it from the printer
Paper feeds, prints garbageThe printer is not speaking ESC/POS, or the wrong code pageRead the command set the printer declares about itself, on the boot slip or in status. If it names anything but an ESC/POS spelling, the node is speaking the wrong language and no tuning fixes it
A print is refused with unsupported_command_setSame cause, caught properlyWorking as intended — it is refusing rather than wasting a roll. Raw byte pass-through is deliberately not subject to it if you want to drive the printer yourself
Prints blank but still cutsThermal paper loaded upside downDrag a fingernail across it: the coated side streaks. Flip the roll
Cuts short, through the contentToo little feed before the cut — the cutter sits above the headRaise the cut-feed lines in config. 8 cleared the bench printer
The last line prints only on the next jobThe printer waits for a zero-length packet when the final packet exactly fills the endpointTurn on the zero-length-packet setting in config
Large receipts stall midwayThe printer’s internal buffer overrunsLower the USB chunk size, or raise the inter-chunk delay. The endpoint recovers from a stall by itself, so this degrades throughput rather than wedging the printer
Status reads as unknownThe printer has no status channelNot a fault. Plenty of inexpensive printers have no inbound endpoint and can never answer a status query — the node reports that as unknown rather than inventing "no faults"
Flowchart of how the status response decides between a real reading and an explicit unknown, including the cache and the mute latch.
Why “I cannot tell” is a separate answer from “paper is fine”. A well-formed wrong number is the failure this whole surface exists to refuse, so a reading that could not be taken is reported as unknown rather than guessed.

The drawer

A drawer reported open while it is shut, and shut while it stands open, is a polarity setting and not a broken switch. The ESC/POS status bit reports the pin level, not the drawer’s state, and which level means open is a property of how that drawer’s switch is wired — so a node cannot work it out. Set the drawer polarity in config; it applies on the next status poll, with no reboot and no re-enumeration.

Take the reading against a till somebody has closed properly, and at least three seconds after a kick. A drawer kicked from a start that was not fully latched slides far enough to look open without tripping the switch, then reads shut while standing visibly open — which looks exactly like a sense line that reports the transition and reverts. It is not.

The scale

A scale reading a steady zero that never moves has usually stopped answering. "Stable at zero" is what a decoder renders for silence, and it is the well-formed wrong number this product exists to refuse — so the node calls it out explicitly rather than showing green.

An idle scale that naps off the USB bus for hours looks the same as one whose cable was pulled, which is why the dwell before a missing scale counts as a fault has a five-minute floor and ships switched off. That floor is a hardware fact, not caution: any threshold under it fires on ordinary sleep.

A node that restarts itself with nobody near it

The node can power-cycle its own USB bus and, if the operator allows it, restart. It escalates against a bus that has stopped working: root-port cycles at 30 seconds, 2 minutes and 10 minutes — about twelve and a half minutes of ladder — then a reboot rung, capped at six cycles in any rolling hour. It announces reaching the cap rather than going quiet.

Three things that will otherwise read as faults:

  • The recovery block is omitted from status entirely when there is nothing to say. Its absence is health, not a missing field.
  • The reboot rung has a brake that survives a software restart: two restarts per power-on session, then refused. Only pulling the plug clears it — which is right, because the person pulling the plug is usually the person who just fixed the supply. It retires itself once the bus has been clean for a whole window.
  • A node can cycle its bus because a peripheral went away, not because anything failed. That is the answer to "it cycled at 2 a.m. and nothing was broken". The status response names the reason in words — "printer gone for 180s".

You set the ceiling: report only, cycles only, or the full ladder including the restart. An unrecognised value is refused rather than silently falling back, because a node reporting a protection level it will not act on is worse than one refusing the setting.

The one fault this does not fix

The recovery ladder does not recover an under-powered bus, and we are not going to claim it does. The bench finding is the opposite: a marginal supply is stochastic, the firmware’s own port cycle never actually drops the 5 V rail on the current hardware, and only a human replugging power has recovered it. The board work that would change that is in development. If a node is cycling repeatedly and the reason names a peripheral that is physically present, suspect the supply and the cabling before anything in software.

When an API call fails

Every failure carries a code, and the code — not the HTTP status alone — is what tells you whether to retry. The short version: 409 and 503 are the node’s current state and are worth retrying; 400, 404, 413 and 422 are your request and are not; 401 needs a credential; 500 means the node took it and failed itself.

Two are worth knowing by name because they look alike and are opposites: a refusal because a restart is already pending is transient and can stand for up to fifteen minutes, and it fires on a node nobody touched — the recovery ladder’s reboot rung holds the same gate an installed image does. A digest mismatch on a firmware upload is permanent: retrying the identical bytes never works.

The full table with a retry column is on error codes.

Still stuck

Take the node id, the firmware version it is running, a paste of its status output, and what you did and what happened, to support. Those four things are most of the answer, and the third one is the reason to paste rather than describe.

Frequently asked questions

The node reboots itself every 15 to 30 minutes and nobody is near it.
That is the USB recovery ladder reaching its reboot rung against a bus fault that will not clear. Read the recovery block in the status response and the enumeration counters beside it. Fix the supply — and if you want the node never to restart itself, lower its recovery ceiling to cycles only.
A print returns 200 but no paper comes out.
Check whether a printer is actually bound. A loopback fallback can mask an unbound printer, so a job is accepted and goes nowhere. The status response tells bound from never-plugged-in from seen-and-gone; the serial log names the fallback explicitly when it happens.
Discovery finds nothing but the IP address works.
Multicast is filtered on that network, or the machine you are searching from has no mDNS resolver. Use the address. Discovery is a convenience, not a dependency — nothing in the print path needs it.
The node joined once and now sits with the error pattern for hours.
That is deliberate. Credentials that have worked even once are trusted through any outage, so a node whose access point is down keeps retrying rather than dropping into setup mode — otherwise a router reboot would strand a whole fleet in a portal. If the network really has changed, hold the B button about 5 seconds to forget it.
Rules and layout print narrower than the paper.
The configured column width is wrong, and it fails silently because nothing on the node can measure paper. Print a boot slip and read its ruler bars: the widest bar that does not wrap is the truth, then set that column count in config.

Related reading