puppetlabs/puppet · error · Puppet::Error

Cannot create #{@resource[:path]}; parent directory #{parent

Error message

Cannot create #{@resource[:path]}; parent directory #{parent} does not exist

What it means

The ensure property's :directory value creates the target with Dir.mkdir, which (unlike `mkdir -p`) cannot create intermediate directories. Puppet guards this explicitly: if File.dirname of the resource path does not exist it raises 'Cannot create <path>; parent directory <parent> does not exist' instead of surfacing Errno::ENOENT.

Source

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

        property.sync
      else
        @resource.write
        @resource.should(:mode)
      end
    end

    # aliasvalue(:present, :file)
    newvalue(:present, :event => :file_created) do
      # Make a file if they want something, but this will match almost
      # anything.
      set_file
    end

    newvalue(:directory, :event => :directory_created) do
      mode = @resource.should(:mode)
      parent = File.dirname(@resource[:path])
      unless Puppet::FileSystem.exist? parent
        raise Puppet::Error,
              "Cannot create #{@resource[:path]}; parent directory #{parent} does not exist"
      end
      if mode
        Puppet::Util.withumask(0o00) do
          Dir.mkdir(@resource[:path], symbolic_mode_to_int(mode, 0o755, true))
        end
      else
        Dir.mkdir(@resource[:path])
      end
      @resource.send(:property_fix)
      return :directory_created
    end

    newvalue(:link, :event => :link_created, :required_features => :manages_symlinks) do
      property = resource.property(:target)
      fail "Cannot create a symlink without a target" unless property

      property.retrieve

View on GitHub (pinned to e227c27540)

Solutions

  1. Declare each parent and order it: `file { '/data/app': ensure => directory } -> file { '/data/app/logs': ensure => directory }`.
  2. Add `require => File['/data/app']` on the child (or `before` on the parent).
  3. For deep trees, generate one resource per level with a defined type.
  4. Re-read the reported parent path for typos — a misspelled segment looks identical to a missing one.

Example fix

// before
file { '/data/app/logs': ensure => directory }

// after: create and order each parent
file { '/data':     ensure => directory }
file { '/data/app': ensure => directory }
->
file { '/data/app/logs': ensure => directory }
Defensive patterns

Strategy: validation

Validate before calling

# Ruby pre-flight
parent = File.dirname(target_path)
unless Puppet::FileSystem.exist?(parent)
  fail("#{parent} does not exist — declare file { '#{parent}': ensure => directory } and order it first")
end

Try / catch

rescue Puppet::Error; on /parent directory .* does not exist/ add the missing parent as an ordered file resource and re-run — the catalog converges incrementally, no manual cleanup needed.

Prevention

When it happens

Trigger: `file { '/data/app/logs': ensure => directory }` when /data/app does not exist yet; the parent resource exists in the catalog but is ordered after the child (missing require/before/->); a typo in one path segment; parents present on some nodes but not others.

Common situations: Assuming recursive mkdir -p semantics; fresh nodes missing mount points or install roots; ordering bugs where the parent directory resource lacks a relationship arrow; modules assuming a package created the parent.

Related errors


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