zpl.tools
Compatibility LayersLabelary Compatibility

Linting & Warnings

Opt-in ZPL linting via the X-Linter and X-Warnings headers

The linter reports problems in your ZPL: unknown or unsupported commands, trimmed or invalid argument values, and render failures. It does not change how the label renders. It makes the renderer's silent defaults visible.

Turn on linting

Linting is off by default. Send the X-Linter: On request header on any label-conversion request, as on Labelary:

curl --request POST 'https://api.zpl.tools/compatibility/labelary/v1/printers/8dpmm/labels/4x6/0' \
  --header 'X-API-Key: YOUR_API_KEY' \
  --header 'X-Linter: On' \
  --header 'Accept: image/png' \
  --data '^XA^FO50,50^FDHello^FS^QQjunk^XZ'

Without the header, or with X-Linter: Off, the response is byte-identical to an unlinted request and carries no X-Warnings header.

The X-Warnings response header

When linting is on and the renderer finds problems, the response carries an X-Warnings header. Each warning is five pipe-delimited fields:

{byteIndex}|{byteSize}|{commandName}|{paramNumber}|{message}
FieldMeaning
byteIndexByte offset of the offending span in the submitted ZPL — the argument itself when the warning is argument-specific, otherwise the command
byteSizeLength in bytes of that span
commandNameCommand name as written, with its prefix (e.g. ^FO, ^BC) — as in observed Labelary output
paramNumber1-based argument number, empty when not argument-specific
messageHuman-readable description

Pipes join multiple warnings. The header reports at most 20 warnings per request, and drops the rest silently, like Labelary.

The ^QQjunk above reports this, byte-identical to what live Labelary returns for the same body:

X-Warnings: 22|3|^QQ||This ZPL command does not exist and was ignored

Reported conditions

ConditionExample message
Command name is not documented ZPLThis ZPL command does not exist and was ignored
Valid ZPL that the renderer does not implementcommand "^PM" is valid ZPL but is not supported ...
Numeric argument has trailing garbage (the renderer trims it, as the ZPL specification requires)Value '10abc' is not a valid number; suffix 'abc' was ignored
The renderer cannot interpret the argument value (uses the default)Value 'ab' is not a valid number and was ignored
Argument value outside its valid range (clamped)Value 5 is less than minimum value 10; used 10 instead
Argument value outside its valid range (kept as written)Value 0 is less than minimum value 1 and was used as written
The label requests a font that does not existFont 'Z' does not exist
Barcode or graphic fails to renderfailed to render Code 128 barcode (^BC): ...
The label references an image that no ~DG stored^XG references image "R:LOGO.GRF" which was never stored ...

The linter does not warn about idiomatic omissions, such as trailing arguments left off a command, as on Labelary. Where the renderer's fallback differs from Labelary's, the message states what the renderer does. Labelary replaces an out-of-range ^BQ magnification with its default. The renderer clamps it to the nearest valid value, and says so.

Conditions never reported

111 of the 231 commands in the reference configure a printer instead of drawing on a label: network settings, sensor calibration, print speed, host status queries, RFID tag writes. The renderer ignores them and reports IGNORED_COMMAND at info severity, which does not reach X-Warnings. Labelary accepts the same commands silently.

A command that changes the label if the renderer implements it reports UNSUPPORTED_COMMAND at warning severity, and reaches the header, as ^PM does above. Labelary does not render those commands and reports nothing, so these warnings are additional to Labelary's output.

The skip policy page lists which commands sit on which side.

Full diagnostics in the viewers

X-Warnings is flat text with a 20-entry limit, as on Labelary. For the full, unlimited diagnostics, paste your ZPL into the online viewer or the desktop app: severity levels (info / warning / error), stable machine-readable codes (e.g. UNKNOWN_COMMAND, IGNORED_COMMAND, ARGUMENT_TRIMMED), and precise source positions. Both show every diagnostic next to the preview, and collapse repeated warnings to one line.

The Diagnostics Reference lists every diagnostic code, severity, and example.