puppetlabs/puppet · error · Puppet::Error
Could not deserialize catalog from
Error message
Could not deserialize catalog from %{format}: %{detail} What it means
In 'puppet apply --catalog <file>' (apply.rb), the catalog text is deserialized with Puppet::Resource::Catalog.convert_from(Puppet::Resource::Catalog.default_format, text); any exception is re-raised as Puppet::Error 'Could not deserialize catalog from ...' with the original detail and backtrace preserved. The format is the catalog's default serialization, so the file must contain exactly that payload.
Solutions
- Read the %{detail} in the message — it carries the original exception naming the exact parse/conversion failure
- Regenerate the catalog with a puppet version identical (or compatible) to the one running puppet apply --catalog
- Pre-validate the file is complete and well-formed (e.g. JSON.parse / jq) before handing it to apply
- Re-fetch a fresh catalog rather than editing the old one
Example fix
# before
puppet apply --catalog /tmp/catalog.json # truncated payload -> Puppet::Error
# after
ruby -rjson -e 'JSON.parse(File.read("/tmp/catalog.json"))' && \
puppet apply --catalog /tmp/catalog.json # regenerate first if this fails Defensive patterns
Strategy: try-catch
Validate before calling
require 'json' parsed = JSON.parse(File.read(catalog_path)) # raises on truncation/syntax first # structural sanity: resources array present raise 'not a catalog' unless parsed['resources'] rescue raise 'not a catalog'
Try / catch
begin
catalog = Puppet::Resource::Catalog.convert_from(fmt, text)
rescue => detail
raise "catalog #{path} unusable (#{detail.message}); regenerate with a matching puppet version"
end Prevention
- Generate and apply catalogs with the same puppet version pair
- Validate transferred catalog files (size/checksum/JSON.parse) before apply
- Keep the %{detail} text from the raised error — it identifies the exact parse fault
When it happens
Trigger: Passing a truncated or hand-edited catalog file; JSON/PSON that is syntactically broken; a catalog produced by a different (usually newer) puppet whose resource serialization this version cannot convert; an effectively empty file.
Common situations: Catalog fetched on one master and applied on an agent with mismatched puppet versions; file corrupted in transfer (partial copy, encoding mangling); using --catalog with a file in the wrong format such as YAML.
Related errors
- Both type and title must be given
- Cannot alias to at ; resource already declared
- Could not find resource
- Could not find resource(s)
- Could not intern from data: Could not find relationship…
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/99274dce21a6bdae.
Report an issue: GitHub.
Appendix: source
Thrown at lib/puppet/application/apply.rb:354
end
def read_catalog(text)
facts = get_facts()
node = get_node()
configured_environment = get_configured_environment(node)
# TRANSLATORS "puppet apply" is a program command and should not be translated
Puppet.override({ :current_environment => configured_environment }, _("For puppet apply")) do
configure_node_facts(node, facts)
# NOTE: Does not set rich_data = true automatically (which would ensure always reading catalog with rich data
# on (seemingly the right thing to do)), but that would remove the ability to test what happens when a
# rich catalog is processed without rich_data being turned on.
format = Puppet::Resource::Catalog.default_format
begin
catalog = Puppet::Resource::Catalog.convert_from(format, text)
rescue => detail
raise Puppet::Error, _("Could not deserialize catalog from %{format}: %{detail}") % { format: format, detail: detail }, detail.backtrace
end
# Resolve all deferred values and replace them / mutate the catalog
Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, catalog, configured_environment, Puppet[:preprocess_deferred])
catalog.to_ral
end
end
def apply_catalog(catalog)
configurer = Puppet::Configurer.new
configurer.run(:catalog => catalog, :pluginsync => false)
end
# Returns facts or nil
#
def get_facts
facts = nil
unless Puppet[:node_name_fact].empty?View on GitHub (pinned to e227c27540)