puppetlabs/puppet · error · Puppet::Error

Could not read #{ftype} #{resource.title}: #{detail}

Error message

Could not read #{ftype} #{resource.title}: #{detail}

What it means

During file content sync, data_sync#retrieve_checksum calls the checksum property's sum_file on the current on-disk file; any exception is wrapped as Puppet::Error 'Could not read <ftype> <title>: <detail>'. Directories, links, fifos, and sockets are skipped, and a missing stat yields :absent — the raise comes from actually reading the file.

Source

Thrown at lib/puppet/type/file/data_sync.rb:91

        end
        DateTime.parse(current) >= DateTime.parse(desired)
      rescue => detail
        self.fail Puppet::Error, "Resource with checksum_type #{checksum_type} didn't contain a date in #{current} or #{desired}", detail.backtrace
      end
    end

    def retrieve_checksum(resource)
      stat = resource.stat
      return :absent unless stat

      ftype = stat.ftype
      # Don't even try to manage the content on directories or links
      return nil if %w[directory link fifo socket].include?(ftype)

      begin
        resource.parameter(:checksum).sum_file(resource[:path])
      rescue => detail
        raise Puppet::Error, "Could not read #{ftype} #{resource.title}: #{detail}", detail.backtrace
      end
    end

    def contents_sync(param)
      return_event = param.resource.stat ? :file_changed : :file_created
      resource.write(param)
      return_event
    end
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Check readability as the agent user: `sudo -u puppet head -c1 /path` and inspect ls -l / getfacl.
  2. Fix ownership or manage owner/mode on the resource so the agent can read it.
  3. Check SELinux: `ausearch -m avc -ts recent`, then restorecon the path.
  4. If it is a race, run the agent when other deployment tooling is quiet.

Example fix

# before: agent runs non-root against a 0600 root-owned file
# -> Could not read file /etc/secrets/app.key: Permission denied

# after: run the agent as root and converge permissions explicitly
file { '/etc/secrets/app.key':
  ensure => file,
  owner  => 'root',
  group  => 'app',
  mode   => '0640',
  source => 'puppet:///modules/app/app.key',
}
Defensive patterns

Strategy: validation

Validate before calling

# Ruby pre-flight before managing content
begin
  st = File.lstat(path)
  unless %w[directory link fifo socket].include?(st.ftype)
    fail("#{path} not readable by uid #{Process.uid}") unless File.readable?(path)
  end
rescue Errno::ENOENT
  # absent is fine — content will simply be created
end

Try / catch

rescue Puppet::Error => e; the message starts with 'Could not read' and embeds the original cause — log it, check ACLs/SELinux for that exact path, fix readability, then re-run; the agent is idempotent and will converge on the second pass.

Prevention

When it happens

Trigger: A file resource managing content on a file the agent user cannot read (mode 0600 owned by another user, agent running non-root); SELinux denying read; the path vanishing between stat and sum_file (race with another tool); unusual file types on the platform.

Common situations: Running puppet as a non-privileged user over root-owned files; SELinux contexts on RHEL; ACL-restricted files; deployment tools and Puppet racing on the same path.

Related errors


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