puppetlabs/puppet · error · Puppet::Error

Could not rename corrupt %{filename}; remove manually

Error message

Could not rename corrupt %{filename}; remove manually

What it means

Puppet::Util::Storage.load (storage.rb:65) safe_loads the agent state file (class checksumfile, default $vardir/state/state.yaml). On Puppet::Util::Yaml::YamlLoadError it logs 'Checksumfile ... is corrupt; replacing' and tries File.rename(filename, filename + '.bad'). If THAT rename raises (EACCES/EROFS/EPERM, wrong user, or '.bad' destination conflicts, notably on Windows where rename onto an existing file fails), it raises Puppet::Error 'Could not rename corrupt <file>; remove manually' chained with the original load error's backtrace.

Source

Thrown at lib/puppet/util/storage.rb:65

    filename = Puppet[:statefile]

    unless Puppet::FileSystem.exist?(filename)
      init if @@state.nil?
      return
    end
    unless File.file?(filename)
      Puppet.warning(_("Checksumfile %{filename} is not a file, ignoring") % { filename: filename })
      return
    end
    Puppet::Util.benchmark(:debug, "Loaded state in %{seconds} seconds") do
      @@state = Puppet::Util::Yaml.safe_load_file(filename, [Symbol, Time])
    rescue Puppet::Util::Yaml::YamlLoadError => detail
      Puppet.err _("Checksumfile %{filename} is corrupt (%{detail}); replacing") % { filename: filename, detail: detail }

      begin
        File.rename(filename, filename + ".bad")
      rescue
        raise Puppet::Error, _("Could not rename corrupt %{filename}; remove manually") % { filename: filename }, detail.backtrace
      end
    end

    unless @@state.is_a?(Hash)
      Puppet.err _("State got corrupted")
      init
    end
  end

  def self.stateinspect
    @@state.inspect
  end

  def self.store
    Puppet.debug "Storing state"

    Puppet.info _("Creating state file %{file}") % { file: Puppet[:statefile] } unless Puppet::FileSystem.exist?(Puppet[:statefile])

View on GitHub (pinned to e227c27540)

Solutions

  1. Manually move the file aside as an admin: mv /opt/puppetlabs/puppet/cache/state/state.yaml /tmp/ (or /var/lib/puppet/state/state.yaml on older layouts); puppet rebuilds it.
  2. Fix ownership/permissions of the state directory so the puppet service user can write (chown -R puppet:puppet $vardir).
  3. Stop mixing root and non-root runs against the same vardir; pin the agent to one user via systemd/launchd config.
  4. If on a read-only mount, relocate $vardir (puppet config set vardir) to writable storage.

Example fix

// before
# agent run fails: Could not rename corrupt /var/lib/puppet/state/state.yaml; remove manually

// after (remediation shell)
// systemctl stop puppet
// mv /var/lib/puppet/state/state.yaml{,.manual-bak}
// chown -R puppet:puppet /var/lib/puppet
// systemctl start puppet
Defensive patterns

Strategy: try-catch

Validate before calling

f = Puppet::Util::Storage.checksumfile
if File.exist?(f) && !(File.readable?(f) && File.writable?(File.dirname(f)))
  raise Puppet::Error, "cannot manage corrupt state file #{f}: fix ownership first"
end

Try / catch

begin
  Puppet::Util::Storage.load
rescue Puppet::Error => e
  raise unless e.message.include?('remove manually')
  FileUtils.mv(Puppet::Util::Storage.checksumfile, Puppet::Util::Storage.checksumfile + '.manual') rescue nil
  Puppet::Util::Storage.load # one remediated retry; state rebuilds from scratch
end

Prevention

When it happens

Trigger: state.yaml corrupted (crash mid-write, disk full) AND the puppet process lacking permission to rename it: agent run as non-root over a root-owned cache dir; /var/lib/puppet on a read-only mount; a leftover state.yaml.bad blocking the rename on Windows.

Common situations: Mixing root and non-root puppet runs on the same $vardir; unclean shutdown during catalog application; restricted containers with read-only /var; restored backups that changed file ownership.

Related errors


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