puppetlabs/puppet · error · Puppet::Error

Can not create #{@resource.title}; parent directory does not

Error message

Can not create #{@resource.title}; parent directory does not exist

What it means

ensure#check runs before syncing any creation (file, link, present). If File.dirname of the resource path does not exist, Puppet raises 'Can not create <title>; parent directory does not exist' — the same guard as the directory branch, applied to every ensure value that creates something.

Source

Thrown at lib/puppet/type/file/ensure.rb:152

        should = source.checksum
      else
        should = property.should
      end
      if should == :absent
        is = property.retrieve
      else
        is = :absent
      end

      property.change_to_s(is, should)
    end

    # Check that we can actually create anything
    def check
      basedir = File.dirname(@resource[:path])

      if !Puppet::FileSystem.exist?(basedir)
        raise Puppet::Error,
              "Can not create #{@resource.title}; parent directory does not exist"
      elsif !FileTest.directory?(basedir)
        raise Puppet::Error,
              "Can not create #{@resource.title}; #{dirname} is not a directory"
      end
    end

    # We have to treat :present specially, because it works with any
    # type of file.
    def insync?(currentvalue)
      unless currentvalue == :absent or resource.replace?
        return true
      end

      if should == :present
        !(currentvalue.nil? or currentvalue == :absent)
      else
        super(currentvalue)

View on GitHub (pinned to e227c27540)

Solutions

  1. Declare and order the parent directory resource before the child (require/before/->).
  2. Create install roots in provisioning (package post-install, cloud-init, kickstart) or an early class.
  3. Run `puppet agent -t --debug` to see exactly which parent path is reported missing.
  4. For many nested files, manage the directory tree explicitly or use an ensure => directory root with source recursion.

Example fix

// before
file { '/opt/app/bin/tool':
  ensure => file,
  source => 'puppet:///modules/app/tool',
}

// after
file { '/opt/app/bin': ensure => directory }
->
file { '/opt/app/bin/tool':
  ensure => file,
  source => 'puppet:///modules/app/tool',
}
Defensive patterns

Strategy: validation

Validate before calling

# Ruby pre-flight
basedir = File.dirname(resource_path)
fail("#{basedir} missing — provision it or add an ordered file resource") unless Puppet::FileSystem.exist?(basedir)

Try / catch

rescue Puppet::Error; on /parent directory does not exist/ add the parent directory resource with a before/require relationship to the failing resource and re-run the agent.

Prevention

When it happens

Trigger: `file { '/opt/app/bin/tool': ensure => file, source => ... }` with /opt/app/bin absent; `ensure => link` under a nonexistent directory; `ensure => present` on a new nested path; parents managed later in the catalog without ordering.

Common situations: Fresh nodes where install directories are not provisioned yet; a module assuming a package creates the parent; purge workflows that removed the parent first; new modules applied before their prerequisite classes.

Related errors


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