puppetlabs/puppet · error · Puppet::Error
launchctl list failed to return any data.
Error message
launchctl list failed to return any data.
What it means
The launchd provider's job_list class method runs launchctl list and immediately raises if the command produced nil output (execute returned nothing at all, distinct from an empty-but-successful string). A separate rescue converts Puppet::ExecutionFailure into 'Unable to determine status'. The nil check exists because the code then calls output.split, which would otherwise raise NoMethodError.
Source
Thrown at lib/puppet/provider/service/launchd.rb:190
if by_label.has_key? label
{ label => by_label[label] }
else
raise Puppet::Error, "Unable to find launchd plist for job: #{label}"
end
end
else
# caller wants the whole map
by_label
end
end
# This status method lists out all currently running services.
# This hash is returned at the end of the method.
def self.job_list
@job_list = Hash.new
begin
output = launchctl :list
raise Puppet::Error, "launchctl list failed to return any data." if output.nil?
output.split("\n").each do |line|
@job_list[line.split(/\s/).last] = :running
end
rescue Puppet::ExecutionFailure => e
raise Puppet::Error.new("Unable to determine status of #{resource[:name]}", e)
end
@job_list
end
# Read a plist, whether its format is XML or in Apple's "binary1"
# format.
def self.read_plist(path)
Puppet::Util::Plist.read_plist_file(path)
end
# Read overrides plist, retrying if necessary
def self.read_overridesView on GitHub (pinned to e227c27540)
Solutions
- Run launchctl list as the same user puppet uses and confirm it prints lines
- Stop forcing provider => 'launchd' on non-macOS nodes; let the provider confine to darwin pick it
- Check which launchctl resolves: which -a launchctl, and remove wrappers that eat stdout
- Repair the OS binary / reimage broken hosts rather than suppressing the error
Defensive patterns
Strategy: validation
Validate before calling
out=$(launchctl list 2>&1) if [ -z "$out" ]; then echo "launchctl returned no data — repair OS or stop forcing launchd provider"; fi
Prevention
- Let provider confines choose launchd only on darwin; never hardcode provider => 'launchd' in shared profiles
- Keep PATH for the agent free of wrapper scripts shadowing system binaries
- Include a launchctl sanity probe in macOS host acceptance checks
When it happens
Trigger: Calling self.job_list (status/prefetch paths of the launchd provider) in an environment where the launchctl binary resolves but returns nothing — a broken/shadowed launchctl, an execution wrapper swallowing output, or a non-macOS sandbox where the provider was forced via provider => 'launchd'.
Common situations: Running puppet inside CI containers or over a non-macOS test host with the provider forced for spec runs; macOS images where launchctl is damaged or SIP/permissions block it; wrapper scripts in PATH intercepting system binaries.
Related errors
- Unable to find launchd plist for job: #{label}
- Unable to read overrides plist, too many attempts
- Unable to parse launchd plist at path: #{job_path}
- puppet.plans/invalid-name
- Invalid #{field} given for user #{user_name}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/fca65c124ef53ca6.
Report an issue: GitHub.