Sign In
Products
ZPL ViewerBarcode GeneratorImage → ZPLZPL cheat sheetLabel DesignerTemplate Gallery
Developers
API QuickstartAPI ReferenceMCP ServerBulk GenerationWebhooksSDKs & ExamplesLimitsDirectPrint agent NewGitHub ActionVS Code extensionOn-Premise
Solutions
Logistics & ShippingE-CommerceERP & WMSManufacturingRetailHealthcare & LaboratoryAll solutions
Tools
ZPL Diagnostics HubZPL DebuggerSize & DPI AnalyzerDPI ConverterBarcode fit calculatorShipping Label AnalyzerFont InspectorOrientation DebuggerCalibration AssistantPrinter Compatibility CheckerBarcode Readability CheckerPrinter Language DetectorThermal Printer Test PackZPL ToolsEPL ToolsTSPL ToolsCPCL ToolsPrinter Language ConverterAll ToolsGuidesPricing
Language
EnglishTürkçeDeutsch
Home›Guides›Printing ZPL on macOS and Linux with a CUPS Raw Queue

Printing ZPL on macOS and Linux with a CUPS Raw Queue

Published:

ZPL is a printer language: the printer itself renders it. On macOS and Linux the print system is CUPS, and CUPS normally does the opposite of what a ZPL job needs — it runs every job through filters that convert documents into printer commands. Your job already is printer commands, so the queue must pass bytes through untouched. That is what a raw queue does.

The one rule: the queue must be raw

If the queue has a driver or filter attached, one of two things happens: the filter rejects the job, or — the classic symptom — the printer dutifully prints your ^XA…^XZ source as visible text on the label. The label is not wrong; the queue treated ZPL as a document. Nothing in the ZPL can fix that: it is a queue setting.

Creating a raw queue

Both macOS and Linux ship lpadmin:

sudo lpadmin -p zebra-raw -E -v socket://192.168.1.50:9100 -m raw

-p names the queue, -E enables it, -v is the device URI (here the printer's IP with raw port 9100), and -m raw says: no driver, no filtering. For a USB printer, find the URI first with lpinfo -v and use the usb://… line it prints.

Recent CUPS versions print a deprecation warning for raw queues. They still work; the warning is about CUPS's future direction, and the direct-socket alternative below does not depend on CUPS at all.

Sending a label

lp -d zebra-raw label.zpl

If you must use an existing, driver-backed queue, you can ask for pass-through per job with lp -d zebra -o raw label.zpl — but a dedicated raw queue is harder to get wrong.

macOS notes

The printer dialogs in System Settings want to pick a driver or AirPrint — both are for documents, not for raw ZPL, so set the queue up from the terminal with lpadmin as above. If you prefer a browser UI, the CUPS web interface is off by default; enable it with cupsctl WebInterface=yes and open localhost:631.

Checking the queue

lpstat -p lists queues and their state, lpstat -o lists waiting jobs, cancel -a clears them. A job that reports "completed" only means CUPS handed the bytes over — like port 9100 itself, it is not proof the label printed correctly. Paste the ZPL into the online viewer before sending: paper has no undo.

When you don't need CUPS at all

For a one-off job, sending straight to the printer's TCP port 9100 is simpler — no queue to configure; see how to send ZPL to a network printer. What CUPS adds is spooling: named queues, ordering, retries and permissions. If several people or systems share one printer, that layer earns its keep. For the wider driver question — all three raw routes, and when a real driver helps — see printing ZPL without a driver.

Labelixa DirectPrint

If your labels are rendered or stored in Labelixa, the DirectPrint agent is the local-helper pattern run for you: a small program on a computer in the printer's network that collects print jobs from the API and hands them to the printer — over the network or through a USB printer's print queue. It opens no inbound port. Download and setup: /download

Printing ZPL to a USB Zebra printer from the cloud

Frequently asked questions

Why does my Zebra printer print the ZPL code as text?

Because the CUPS queue has a driver or filter attached that treats the ZPL source as a document. Make the queue raw (lpadmin with -m raw) or pass -o raw per job; nothing inside the ZPL itself can fix a queue setting.

Do I need a driver to print ZPL on macOS or Linux?

No. The printer's own firmware renders ZPL, so the queue only has to pass bytes through untouched — that is exactly what a raw CUPS queue does. A driver is for converting documents, which a ZPL job by definition is not.

CUPS warns that raw queues are deprecated — will this stop working?

Raw queues still work; the warning is about CUPS's future direction. If it ever bites, sending straight to the printer's TCP port 9100 does not depend on CUPS at all and achieves the same pass-through.

Related guides

Printing ZPL to a USB Zebra printer from the cloud

A USB label printer has no port 9100. How the operating system's print queue carries raw ZPL, and how the Labelixa agent connects that queue to a cloud API.

Printing ZPL from a browser

A browser cannot open a socket to port 9100. The three patterns that actually deliver ZPL from a web app, and what each one costs.

Why did my label print on the wrong printer?

Labels landing on the wrong printer are an identity problem, not bad luck: queue names, DHCP leases and shared drivers. How to diagnose and stop it.

Printing ZPL Without a Printer Driver

Why ZPL needs no driver, three ways to send it raw — direct socket, CUPS raw queue, Windows Generic/Text Only — and when a driver helps.

Try your own ZPL code →