puppetlabs/puppet · error · Puppet::Util::Plist::FormatError
Unknown plist format #{format}
Error message
Unknown plist format #{format} What it means
Puppet::Util::Plist.to_format (plist.rb:141) maps a format symbol to a CFPropertyList constant; only :xml, :binary, and :plain are recognized, anything else raises FormatError. It is reached through Puppet::Util::Plist.write_plist_file(plist, file_path, format), used by Puppet's macOS providers (directoryservice writes :binary, launchd writes the default :xml).
Source
Thrown at lib/puppet/util/plist.rb:141
# Helper method to assist in reading a file with an offset value. It's its
# own method for stubbing purposes
#
# @api private
def read_file_with_offset(file_path, offset)
IO.read(file_path, offset)
end
def to_format(format)
case format.to_sym
when :xml
CFPropertyList::List::FORMAT_XML
when :binary
CFPropertyList::List::FORMAT_BINARY
when :plain
CFPropertyList::List::FORMAT_PLAIN
else
raise FormatError, "Unknown plist format #{format}"
end
end
# This method will write a plist file using a specified format (or XML
# by default)
def write_plist_file(plist, file_path, format = :xml)
plist_to_save = CFPropertyList::List.new
plist_to_save.value = CFPropertyList.guess(plist)
plist_to_save.save(file_path, to_format(format), :formatted => true)
rescue IOError => e
Puppet.err(_("Unable to write the file %{file_path}. %{error}") % { file_path: file_path, error: e.inspect })
end
def dump_plist(plist_data, format = :xml)
plist_to_save = CFPropertyList::List.new
plist_to_save.value = CFPropertyList.guess(plist_data)
plist_to_save.to_str(to_format(format), :formatted => true)
endView on GitHub (pinned to e227c27540)
Solutions
- Use one of the three supported symbols: :xml, :binary, :plain (omitting format defaults to :xml).
- Whitelist-validate at the boundary: raise your own error for anything outside %i[xml binary plain].
- Normalize user input: format.to_s.strip.downcase.to_sym before passing.
- Rescue Puppet::Util::Plist::FormatError and report the supported formats.
Example fix
// before Puppet::Util::Plist.write_plist_file(plist, path, requested_format) # requested_format = 'XML' // after fmt = requested_format.to_s.strip.downcase.to_sym raise ArgumentError, "format must be xml|binary|plain" unless %i[xml binary plain].include?(fmt) Puppet::Util::Plist.write_plist_file(plist, path, fmt)
Defensive patterns
Strategy: validation
Validate before calling
fmt = fmt.to_s.strip.downcase.to_sym raise ArgumentError, 'format must be :xml, :binary or :plain' unless %i[xml binary plain].include?(fmt)
Type guard
def plist_format?(f) %i[xml binary plain].include?(f.to_s.strip.downcase.to_sym) end
Try / catch
begin
Puppet::Util::Plist.write_plist_file(data, path, fmt)
rescue Puppet::Util::Plist::FormatError => e
Puppet.err("#{e.message}; defaulting to :xml")
Puppet::Util::Plist.write_plist_file(data, path, :xml)
end Prevention
- Normalize user-supplied formats (downcase + to_sym) and whitelist to %i[xml binary plain].
- Remember write_plist_file already defaults to :xml; omit the argument unless a specific format is required.
When it happens
Trigger: Plist.write_plist_file(data, path, :json); Plist.write_plist_file(data, path, 'XML') (case mismatch after to_sym); Plist.write_plist_file(data, path, :bplist) or :xml1 (made-up names); passing a format through a config string that was never whitelisted.
Common situations: Custom macOS provider code adding new plist output; configuration-driven format selection where users type 'xml-1.0' or 'binary-plist'; copying example code from CFPropertyList docs that uses its own format constants.
Related errors
- puppet.plans/invalid-name
- 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}
- One or more file(s) specified did not exist: %{files}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/480b1ba332055a9c.
Report an issue: GitHub.