puppetlabs/puppet · error · Puppet::Error
Mac OS X PKG DMGs must specify a source string ending in .dm
Error message
Mac OS X PKG DMGs must specify a source string ending in .dmg or flat .pkg file
What it means
Raised by `installpkgdmg` (lib/puppet/provider/package/pkgdmg.rb:80), Puppet's macOS pkgdmg provider. The `source` attribute must end in `.dmg` or `.pkg` (case-insensitive) because the suffix selects the strategy: mount a disk image with hdiutil, or install a flat package with `installer -pkg`. Any other extension fails fast before anything is downloaded.
Source
Thrown at lib/puppet/provider/package/pkgdmg.rb:80
end
def self.installpkg(source, name, orig_source)
installer "-pkg", source, "-target", "/"
# Non-zero exit status will throw an exception.
Puppet::FileSystem.open("/var/db/.puppet_pkgdmg_installed_#{name}", nil, "w:UTF-8") do |t|
t.print "name: '#{name}'\n"
t.print "source: '#{orig_source}'\n"
end
end
def self.installpkgdmg(source, name)
unless Puppet::Util::HttpProxy.no_proxy?(source)
http_proxy_host = Puppet::Util::HttpProxy.http_proxy_host
http_proxy_port = Puppet::Util::HttpProxy.http_proxy_port
end
unless source =~ /\.dmg$/i || source =~ /\.pkg$/i
raise Puppet::Error, _("Mac OS X PKG DMGs must specify a source string ending in .dmg or flat .pkg file")
end
require 'open-uri' # Dead code; this is never used. The File.open call 20-ish lines south of here used to be Kernel.open but changed in '09. -NF
cached_source = source
tmpdir = Dir.mktmpdir
ext = /(\.dmg|\.pkg)$/i.match(source)[0]
begin
if %r{\A[A-Za-z][A-Za-z0-9+\-.]*://} =~ cached_source
cached_source = File.join(tmpdir, "#{name}#{ext}")
args = ["-o", cached_source, "-C", "-", "-L", "-s", "--fail", "--url", source]
if http_proxy_host and http_proxy_port
args << "--proxy" << "#{http_proxy_host}:#{http_proxy_port}"
elsif http_proxy_host and !http_proxy_port
args << "--proxy" << http_proxy_host
end
begin
curl(*args)
Puppet.debug "Success: curl transferred [#{name}] (via: curl #{args.join(' ')})"View on GitHub (pinned to e227c27540)
Solutions
- Mirror the artifact as a .dmg or a flat .pkg and point `source` at a URL that literally ends with that extension.
- Strip query strings/fragments from the URL so the regex sees the extension.
- For .zip or .mpkg payloads, repackage them (a flat .pkg inside a dmg) or use a different provider.
- Verify case: the check is case-insensitive, so only the extension itself matters.
Example fix
# before
package { 'firefox':
ensure => installed,
provider => pkgdmg,
source => 'https://download.example.com/firefox-latest.tar.bz2',
}
# after
package { 'firefox':
ensure => installed,
provider => pkgdmg,
source => 'https://download.example.com/mirror/Firefox-115.0.dmg',
} Defensive patterns
Strategy: validation
Validate before calling
# Validate the source extension before declaring the resource
source='https://mirror.example.com/Firefox-115.0.dmg'
[[ "$source" =~ \.(dmg|pkg)$ ]] || { echo "source must end in .dmg or .pkg"; exit 1; } Prevention
- Mirror vendor artifacts under URLs whose final path ends in .dmg or .pkg.
- Strip query strings/fragments from download URLs.
- Repackage .zip/.mpkg payloads as flat .pkg or .dmg before using pkgdmg.
When it happens
Trigger: `package { 'Firefox': provider => pkgdmg, source => 'https://.../Firefox.tar.bz2' }`, a CDN/redirect URL whose final path lacks the extension, or a URL with a query string after the filename.
Common situations: Pointing source at a .zip archive or an .mpkg bundle (not supported - only flat .pkg); vendor download links that redirect to extension-less URLs; typos in the source.
Related errors
- Mac OS X PKG DMGs must specify a package source.
- No disk entities returned by mount at %{path}
- Mac OS X PKG DMGs must specify a package name.
- puppet.plans/invalid-name
- Unable to find launchd plist for job: #{label}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/cd44dcda71e053b3.
Report an issue: GitHub.