puppetlabs/puppet · error · Puppet::Error

Unable to find a common checksum type between agent '%{agent

Error message

Unable to find a common checksum type between agent '%{agent_type}' and master '%{master_type}'.

What it means

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.

Source

Thrown at lib/puppet/indirector/catalog/compiler.rb:313

          metadata.content_uri = get_content_uri(metadata, metadata.source, environment_path)
          log_metadata_inlining

          # If the file is in the environment directory, we can safely inline
          catalog.metadata[resource.title] = metadata
        else
          # Log a profiler event that we skipped this file because it is not in an environment.
          log_file_outside_environment
        end
      end
    end
  end

  # Compile the actual catalog.
  def compile(node, options)
    if node.environment && node.environment.static_catalogs? && options[:static_catalog] && options[:code_id]
      # Check for errors before compiling the catalog
      checksum_type = common_checksum_type(options[:checksum_type])
      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
    end

    escaped_node_name = node.name.gsub(/%/, '%%')
    if checksum_type
      if node.environment
        escaped_node_environment = node.environment.to_s.gsub(/%/, '%%')
        benchmark_str = _("Compiled static catalog for %{node} in environment %{environment} in %%{seconds} seconds") % { node: escaped_node_name, environment: escaped_node_environment }
        profile_str   = _("Compiled static catalog for %{node} in environment %{environment}") % { node: node.name, environment: node.environment }
      else
        benchmark_str = _("Compiled static catalog for %{node} in %%{seconds} seconds") % { node: escaped_node_name }
        profile_str   = _("Compiled static catalog for %{node}") % { node: node.name }
      end
    elsif node.environment
      escaped_node_environment = node.environment.to_s.gsub(/%/, '%%')
      benchmark_str = _("Compiled catalog for %{node} in environment %{environment} in %%{seconds} seconds") % { node: escaped_node_name, environment: escaped_node_environment }
      profile_str   = _("Compiled catalog for %{node} in environment %{environment}") % { node: node.name, environment: node.environment }
    else
      benchmark_str = _("Compiled catalog for %{node} in %%{seconds} seconds") % { node: escaped_node_name }

View on GitHub (pinned to e227c27540)

Solutions

  1. Set supported_checksum_types on the agent to include an algorithm the master allows, e.g. supported_checksum_types = sha256 on both sides
  2. On the master, ensure Puppet[:supported_checksum_types] includes at least one of the agent's algorithms
  3. As a stopgap, disable static catalogs for the mismatched node (static_catalogs = false) so checksum negotiation is skipped

Example fix

# before (agent puppet.conf)
# supported_checksum_types = md5   (master allows only sha256)
# => Puppet::Error: Unable to find a common checksum type ...

# after
supported_checksum_types = sha256
Defensive patterns

Strategy: validation

Validate before calling

# ruby
agent_types = Array(Puppet[:supported_checksum_types]).map(&:to_s)
negotiated = agent_types & master_known_types
Puppet.warning 'no common checksum type' if negotiated.empty?
opts[:checksum_type] = negotiated unless negotiated.empty?

Type guard

def checksum_types_compatible?(agent_types, master_types)
  (Array(agent_types).map(&:to_s) & Array(master_types).map(&:to_s)).any?
end

Try / catch

begin
  compiler.compile(node, options)
rescue Puppet::Error => e
  raise unless e.message.include?('common checksum type')
  options[:checksum_type] = %w[sha256]
  retry
end

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/9963f72d4d3289b1. Report an issue: GitHub.