puppetlabs/puppet · error · Puppet::ParseError

Execution of config_version command `%{cmd}` failed: %{messa

Error message

Execution of config_version command `%{cmd}` failed: %{message}

What it means

EnvironmentConfig's TypeCollection#version executes the command from the environment's config_version setting (environment.conf or puppet.conf) on every catalog compile to stamp the report with a version string. If Puppet::Util::Execution.execute fails (non-zero exit, missing command), the Puppet::ExecutionFailure is wrapped in Puppet::ParseError including the command and its error output, and compilation aborts.

Source

Thrown at lib/puppet/resource/type_collection.rb:181

    end
  end

  def parse_failed?
    @parse_failed
  end

  def version
    unless defined?(@version)
      if environment.config_version.nil? || environment.config_version == ""
        @version = Time.now.to_i
      else
        @version = Puppet::Util::Execution.execute([environment.config_version]).to_s.strip
      end
    end

    @version
  rescue Puppet::ExecutionFailure => e
    raise Puppet::ParseError, _("Execution of config_version command `%{cmd}` failed: %{message}") % { cmd: environment.config_version, message: e.message }, e.backtrace
  end

  private

  COLON_COLON = "::"

  # Resolve namespaces and find the given object.  Autoload it if
  # necessary.
  def find_or_load(name, type)
    # always lock the environment before locking the type collection
    @environment.lock.synchronize do
      @lock.synchronize do
        # Name is always absolute, but may start with :: which must be removed
        fqname = (name[0, 2] == COLON_COLON ? name[2..] : name)

        result = send(type, fqname)
        unless result
          if @notfound[fqname] && Puppet[:ignoremissingtypes]

View on GitHub (pinned to e227c27540)

Solutions

  1. Run the exact command string manually as the puppet service user and fix whatever makes it fail (executable bit, shebang, permissions).
  2. Make the script failure-proof: fall back internally, e.g. `git rev-parse --short HEAD 2>/dev/null || date +%s`, so it always exits 0.
  3. Use an absolute path for the command and avoid relying on PATH.
  4. If the hook is not needed, blank or remove the config_version setting — version falls back to the compile timestamp (Time.now.to_i).

Example fix

# environment.conf — before
config_version=/usr/local/bin/git-version.sh
# git-version.sh: #!/bin/sh\ngit rev-parse --short HEAD   # fails outside a repo

# after — script always succeeds
#!/bin/sh\ncd /etc/puppetlabs/code/environments/production || exit 1\ngit rev-parse --short HEAD 2>/dev/null || date +%s
Defensive patterns

Strategy: try-catch

Validate before calling

# smoke-test the hook before relying on it
cmd = environment.config_version
exitstatus = Puppet::Util::Execution.execute([cmd], failonfail: false).exitstatus if cmd && !cmd.empty?
raise ArgumentError, "config_version hook broken (exit #{exitstatus})" if exitstatus && !exitstatus.zero?

Try / catch

begin
  version = type_collection.version
rescue Puppet::ParseError => e
  raise unless e.message.include?('config_version')
  Puppet.warning("config_version failed (#{e.message}); using timestamp")
  version = Time.now.to_i
end

Prevention

When it happens

Trigger: config_version = /usr/local/bin/git-version.sh where the script is missing, not executable, has a bad shebang, or exits non-zero; a `git rev-parse HEAD` hook run outside the git repo; permission denied when the puppet user cannot read the repo; command not on the PATH of the service.

Common situations: Git-based deployment hooks (`config_version=/usr/bin/git --git-dir ... rev-parse HEAD`); scripts that assume a login shell PATH or environment variables; moving environments to a new server without the hook's dependencies.

Related errors


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