How to Debug Container Issues Using Container System Logs and Boot Logs
Use container system logs to diagnose daemon-level issues across the com.apple.container subsystem, and container logs --boot or container machine logs --boot to inspect VM initialization failures stored in vminitd.log.
Debugging container failures in the apple/container repository requires correlating two distinct log streams: system-level logs emitted by the container daemon and boot logs generated during VM initialization. By leveraging the container CLI commands, you can trace failures from early-stage VM crashes through application-level errors without manually inspecting bundle directories.
Understanding Container Log Types
The container CLI surfaces three distinct log streams, each targeting different failure modes in the virtualization stack.
System Logs
System logs capture OS-level messages from all container services, including the sandbox daemon, networking components, and the vminitd process. According to the source code in Sources/ContainerCommands/System/SystemLogs.swift, these logs filter on the com.apple.container subsystem using the host's unified logging system.
Boot Logs
Boot logs contain the VM's early-boot output written by the init process to vminitd.log within each machine bundle. As defined in Sources/Services/MachineAPIService/Client/MachineBundle.swift, this file tracks initialization script execution and kernel messages before the container's stdio attaches.
StdIO Logs
Standard output and error streams represent the container's application-level output after successful VM boot. The CLI distinguishes between boot and stdio logs by selecting different file handles from the API response.
Accessing System Logs
The container system logs command constructs a log show or log stream command targeting the container subsystem. In SystemLogs.swift (lines 71-78), the implementation builds the argument array dynamically:
var args = ["log"]
args.append(self.follow ? "stream" : "show")
args.append(contentsOf: ["--info", logOptions.debug ? "--debug" : nil].compactMap { $0 })
if !self.follow { args.append(contentsOf: ["--last", last]) }
args.append(contentsOf: ["--predicate", "subsystem = 'com.apple.container'"])
This executes /usr/bin/env log with predicates filtering for the container subsystem.
Common usage patterns:
# Show the most recent 5 minutes of system logs (default)
container system logs
# Follow live system log output
container system logs --follow
# Show the last 30 seconds
container system logs --last 30s
# Include debug-level messages
container system logs --last 10m --debug
System logs are essential when diagnosing sandbox crashes, networking plugin failures, or daemon restarts that occur outside the VM context.
Inspecting Boot Logs
Boot logs reside in vminitd.log within the machine bundle, as defined in Sources/Services/MachineAPIService/Client/MachineBundle.swift:
private static let bootLogFile = FilePath.Component("vminitd.log")
public var bootLog: FilePath { self.path.appending(Self.bootLogFile) }
Both container logs and container machine logs expose a --boot flag to access this file. In MachineLogs.swift (lines 60-62), the implementation selects the appropriate file handle:
let fhs = try await client.logs(id: id)
let fileHandle = boot ? fhs[1] : fhs[0] // fhs[1] = boot, fhs[0] = stdio
Retrieving boot logs:
# View a container's boot log instead of stdio
container logs --boot mycontainer
# View a machine's boot log with last 50 lines
container machine logs --boot --lines 50 mymachine
# Follow the boot log in real-time
container machine logs --boot --follow mymachine
Boot logs reveal init-script failures, missing entitlements detected during startup, and kernel panics that occur before the container runtime attaches.
End-to-End Debugging Workflow
When troubleshooting a failed container start, correlate both log sources to isolate the failure point.
-
Check boot logs first to verify the VM reached the
bootedstate. Ifvminitdexited early, the boot log contains the termination reason. -
Inspect system logs if the boot log ends abruptly or shows "failed to start" messages. Look for sandbox daemon crashes or networking plugin errors in the
com.apple.containersubsystem. -
Review stdio logs only after confirming successful boot. If the VM started but the application failed, the standard output streams contain the relevant error messages.
Example troubleshooting session:
# Step 1: Check for VM initialization failures
container logs --boot mycontainer
# Step 2: If vminitd failed, check daemon logs
container system logs --last 5m
# Step 3: If boot succeeded, inspect application output
container logs mycontainer
Summary
- Use
container system logsto diagnose daemon-level issues in thecom.apple.containersubsystem, including sandbox and networking failures. - Access boot logs via
container logs --bootorcontainer machine logs --bootto inspectvminitd.logfor VM initialization failures. - The implementation in
Sources/ContainerCommands/System/SystemLogs.swiftbuilds unified logging commands, whileSources/ContainerCommands/Machine/MachineLogs.swiftselects betweenfhs[0](stdio) andfhs[1](boot) file handles. - Boot logs stored in
Sources/Services/MachineAPIService/Client/MachineBundle.swifttrack early-stage crashes before stdio attachment. - Correlate both log types by checking boot logs first, then system logs for daemon issues, then stdio logs for application errors.
Frequently Asked Questions
What is the difference between container system logs and container logs --boot?
container system logs queries the host's unified logging system for the com.apple.container subsystem, showing daemon-level messages from services like the sandbox and networking components. container logs --boot reads the vminitd.log file from the machine bundle, showing the VM's early boot output before the container runtime attaches to stdio.
Where are boot logs stored on disk?
According to MachineBundle.swift, boot logs reside in vminitd.log inside each machine bundle directory. The CLI abstracts this path, so you should use container machine logs --boot <machine-id> rather than accessing the file directly.
How do I follow logs in real-time?
Append --follow to either command. For system logs, this uses log stream instead of log show. For boot logs, this tails the vminitd.log file as it grows, useful for watching init scripts execute during VM startup.
Why does my container show no output with container logs but shows errors with --boot?
If the VM fails to initialize properly, the container never reaches the stdio attachment phase. The boot log captures vminitd output during initialization, revealing errors such as missing entitlements or init script failures that occur before the container's standard output streams are established.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →