{"record":{"id":"99274dce21a6bdae","repo":"puppetlabs/puppet","slug":"could-not-deserialize-catalog-from-format-de","errorCode":null,"errorMessage":"Could not deserialize catalog from %{format}: %{detail}","messagePattern":"Could not deserialize catalog from %(.+?): %(.+?)","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/application/apply.rb","lineNumber":354,"sourceCode":"  end\n\n  def read_catalog(text)\n    facts = get_facts()\n    node = get_node()\n    configured_environment = get_configured_environment(node)\n\n    # TRANSLATORS \"puppet apply\" is a program command and should not be translated\n    Puppet.override({ :current_environment => configured_environment }, _(\"For puppet apply\")) do\n      configure_node_facts(node, facts)\n\n      # NOTE: Does not set rich_data = true automatically (which would ensure always reading catalog with rich data\n      # on (seemingly the right thing to do)), but that would remove the ability to test what happens when a\n      # rich catalog is processed without rich_data being turned on.\n      format = Puppet::Resource::Catalog.default_format\n      begin\n        catalog = Puppet::Resource::Catalog.convert_from(format, text)\n      rescue => detail\n        raise Puppet::Error, _(\"Could not deserialize catalog from %{format}: %{detail}\") % { format: format, detail: detail }, detail.backtrace\n      end\n      # Resolve all deferred values and replace them / mutate the catalog\n      Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, catalog, configured_environment, Puppet[:preprocess_deferred])\n\n      catalog.to_ral\n    end\n  end\n\n  def apply_catalog(catalog)\n    configurer = Puppet::Configurer.new\n    configurer.run(:catalog => catalog, :pluginsync => false)\n  end\n\n  # Returns facts or nil\n  #\n  def get_facts\n    facts = nil\n    unless Puppet[:node_name_fact].empty?","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/application/apply.rb#L336-L372","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\npuppet apply --catalog /tmp/catalog.json  # truncated payload -> Puppet::Error\n\n# after\nruby -rjson -e 'JSON.parse(File.read(\"/tmp/catalog.json\"))' && \\\n  puppet apply --catalog /tmp/catalog.json  # regenerate first if this fails","handlingStrategy":"try-catch","validationCode":"require 'json'\nparsed = JSON.parse(File.read(catalog_path)) # raises on truncation/syntax first\n# structural sanity: resources array present\nraise 'not a catalog' unless parsed['resources'] rescue raise 'not a catalog'","typeGuard":null,"tryCatchPattern":"begin\n  catalog = Puppet::Resource::Catalog.convert_from(fmt, text)\nrescue => detail\n  raise \"catalog #{path} unusable (#{detail.message}); regenerate with a matching puppet version\"\nend","preventionTips":["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"],"tags":["catalog","serialization","apply","puppet"],"backgroundTag":"deserialization-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}