Streaming Contract
NDJSON envelopes, command-specific output, heartbeat, backpressure, and signals.
Several CLI commands consume daemon streams, but not every long-running command uses the same output shape. Always check the command's --help before building a parser.
Daemon stream envelope
For commands that expose the daemon stream as JSON, stdout contains one NDJSON envelope per line. Sequence numbers start at 0.
{"seq":0,"type":"data","payload":{"line":"hello"}}
{"seq":1,"type":"heartbeat"}
{"seq":2,"type":"dropped","payload":{"count":12}}
{"seq":3,"type":"end"}end and error are both terminal frames; a stream emits one terminal outcome, not both. An error payload contains code, message, and optional details.
The daemon normally sends a heartbeat every 15 seconds. The CLI exits with code 4 when no frame arrives for 30 seconds. A 256-frame buffer protects producers; after frames are dropped, the count is emitted before the next frame of any type.
Command-specific exceptions
eventsalways writes outer NDJSON stream envelopes and has no plain log-line mode.- Trivy
--jsonwrites its own progress/result payloads, not the outerStreamFrameEnvelope. - Image progress rendering writes to stdout in the current CLI.
- Plain output is command-specific; do not assume that progress always goes to stderr.
Cancellation and exit codes
On SIGINT or SIGTERM, the CLI requests cancellation and exits without promising to drain every in-flight frame.
| Code | Meaning |
|---|---|
0 | Natural completion |
1 | Validation, RPC, or stream error |
2 | CLI argument parsing error |
3 | Daemon discovery or handshake failure |
4 | Heartbeat timeout |
130 | SIGINT |
143 | SIGTERM |
Use dockerman schema to inspect daemon RPC metadata. The schema does not make command-specific Trivy output an outer daemon envelope.