{"record":{"id":"9963f72d4d3289b1","repo":"puppetlabs/puppet","slug":"unable-to-find-a-common-checksum-type-between-agen","errorCode":null,"errorMessage":"Unable to find a common checksum type between agent '%{agent_type}' and master '%{master_type}'.","messagePattern":"Unable to find a common checksum type between agent '%(.+?)' and master '%(.+?)'\\.","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/indirector/catalog/compiler.rb","lineNumber":313,"sourceCode":"          metadata.content_uri = get_content_uri(metadata, metadata.source, environment_path)\n          log_metadata_inlining\n\n          # If the file is in the environment directory, we can safely inline\n          catalog.metadata[resource.title] = metadata\n        else\n          # Log a profiler event that we skipped this file because it is not in an environment.\n          log_file_outside_environment\n        end\n      end\n    end\n  end\n\n  # Compile the actual catalog.\n  def compile(node, options)\n    if node.environment && node.environment.static_catalogs? && options[:static_catalog] && options[:code_id]\n      # Check for errors before compiling the catalog\n      checksum_type = common_checksum_type(options[:checksum_type])\n      raise Puppet::Error, _(\"Unable to find a common checksum type between agent '%{agent_type}' and master '%{master_type}'.\") % { agent_type: options[:checksum_type], master_type: known_checksum_types } unless checksum_type\n    end\n\n    escaped_node_name = node.name.gsub(/%/, '%%')\n    if checksum_type\n      if node.environment\n        escaped_node_environment = node.environment.to_s.gsub(/%/, '%%')\n        benchmark_str = _(\"Compiled static catalog for %{node} in environment %{environment} in %%{seconds} seconds\") % { node: escaped_node_name, environment: escaped_node_environment }\n        profile_str   = _(\"Compiled static catalog for %{node} in environment %{environment}\") % { node: node.name, environment: node.environment }\n      else\n        benchmark_str = _(\"Compiled static catalog for %{node} in %%{seconds} seconds\") % { node: escaped_node_name }\n        profile_str   = _(\"Compiled static catalog for %{node}\") % { node: node.name }\n      end\n    elsif node.environment\n      escaped_node_environment = node.environment.to_s.gsub(/%/, '%%')\n      benchmark_str = _(\"Compiled catalog for %{node} in environment %{environment} in %%{seconds} seconds\") % { node: escaped_node_name, environment: escaped_node_environment }\n      profile_str   = _(\"Compiled catalog for %{node} in environment %{environment}\") % { node: node.name, environment: node.environment }\n    else\n      benchmark_str = _(\"Compiled catalog for %{node} in %%{seconds} seconds\") % { node: escaped_node_name }","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/indirector/catalog/compiler.rb#L295-L331","documentation":"When compiling a static catalog, the compiler intersects the agent-advertised checksum_type list (options[:checksum_type]) with the master's known_checksum_types (from Puppet[:supported_checksum_types]). If the intersection is empty — agent and master agree on no checksum algorithm — Puppet::Error is raised before compiling, because static catalogs embed file checksums and there is no common way to express them.","triggerScenarios":"An agent advertising only md5 against a FIPS-enabled master offering only sha256; a compile request with checksum_type: ['foo'] or a typo'd algorithm name; options[:checksum_type] passed as an unsupported single String.","commonSituations":"FIPS mode on the master disabling md5 while older agents advertise md5 first or only; mixed-version fleets during upgrades where hardened masters and old agents disagree; supported_checksum_types overridden in puppet.conf on either side unintentionally excluding the negotiated algorithm.","solutions":["Set supported_checksum_types on the agent to include an algorithm the master allows, e.g. supported_checksum_types = sha256 on both sides","On the master, ensure Puppet[:supported_checksum_types] includes at least one of the agent's algorithms","As a stopgap, disable static catalogs for the mismatched node (static_catalogs = false) so checksum negotiation is skipped"],"exampleFix":"# before (agent puppet.conf)\n# supported_checksum_types = md5   (master allows only sha256)\n# => Puppet::Error: Unable to find a common checksum type ...\n\n# after\nsupported_checksum_types = sha256","handlingStrategy":"validation","validationCode":"# ruby\nagent_types = Array(Puppet[:supported_checksum_types]).map(&:to_s)\nnegotiated = agent_types & master_known_types\nPuppet.warning 'no common checksum type' if negotiated.empty?\nopts[:checksum_type] = negotiated unless negotiated.empty?","typeGuard":"def checksum_types_compatible?(agent_types, master_types)\n  (Array(agent_types).map(&:to_s) & Array(master_types).map(&:to_s)).any?\nend","tryCatchPattern":"begin\n  compiler.compile(node, options)\nrescue Puppet::Error => e\n  raise unless e.message.include?('common checksum type')\n  options[:checksum_type] = %w[sha256]\n  retry\nend","preventionTips":["Pin supported_checksum_types = sha256 across the fleet (add md5 only where FIPS permits)","Before enabling FIPS on masters, roll agents to sha256-capable versions and settings","Assert a non-empty checksum intersection in compile harnesses before requesting static catalogs"],"tags":["puppet-compiler","static-catalogs","checksum","fips","configuration-mismatch"],"backgroundTag":"checksum-negotiation-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}