puppetlabs/puppet · error · ArgumentError

%{path} does not exist or is not a directory

Error message

%{path} does not exist or is not a directory

What it means

Mount::File#path= validates that the target is an existing directory (FileTest.directory?) before accepting it — unless the path contains % interpolation patterns like %h/%d/%H, which are deliberately not validated (see the FIXME in the source) because the real directory depends on the requesting node.

Source

Thrown at lib/puppet/file_serving/mount/file.rb:57

  # Return the path as appropriate, expanding as necessary.
  def path(node = nil)
    if expandable?
      expand(@path, node)
    else
      @path
    end
  end

  # Set the path.
  def path=(path)
    # FIXME: For now, just don't validate paths with replacement
    # patterns in them.
    if path =~ /%./
      # Mark that we're expandable.
      @expandable = true
    else
      raise ArgumentError, _("%{path} does not exist or is not a directory") % { path: path } unless FileTest.directory?(path)
      raise ArgumentError, _("%{path} is not readable") % { path: path } unless FileTest.readable?(path)

      @expandable = false
    end
    @path = path
  end

  def search(path, request)
    path = complete_path(path, request.node)
    return nil unless path

    [path]
  end

  # Verify our configuration is valid.  This should really check to
  # make sure at least someone will be allowed, but, eh.
  def validate
    raise ArgumentError, _("Mounts without paths are not usable") if @path.nil?

View on GitHub (pinned to e227c27540)

Solutions

  1. On the Puppet server, verify the target: `ls -ld /srv/data` — it must exist and be a directory
  2. Fix the path in fileserver.conf to point at the actual directory
  3. If you used a % pattern (%h, %d, %H) deliberately, remember this check is skipped and the failure will surface later at request time instead

Example fix

# before (fileserver.conf)
[data]
  path /srv/data/current.tar.gz
  allow *

# after
[data]
  path /srv/data
  allow *
Defensive patterns

Strategy: validation

Validate before calling

def servable_dir?(path)
  FileTest.directory?(path)
end

raise "not a directory: #{dir}" unless servable_dir?(dir)

Try / catch

begin
  mount.path = candidate
rescue ArgumentError => e
  raise unless e.message.end_with?('does not exist or is not a directory')
  candidate = ask_operator_for_real_dir(candidate)
  retry
end

Prevention

When it happens

Trigger: A `path /srv/data/conf.txt` line pointing at a regular file; a path to a directory that does not exist on the file server host; a typo'd absolute path in fileserver.conf.

Common situations: Confusing a file path with the directory the mount should expose; moving the served directory without updating fileserver.conf; typos or stale paths after storage migration.

Related errors


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