{"record":{"id":"cf2da6892d0864c0","repo":"puppetlabs/puppet","slug":"puppet-urls-are-not-supported-as-gem-sources-cf2da6","errorCode":null,"errorMessage":"puppet:// URLs are not supported as gem sources","messagePattern":"puppet:// URLs are not supported as gem sources","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/provider/package/puppetserver_gem.rb","lineNumber":107,"sourceCode":"\n    command_options << '--no-document'\n\n    if resource[:source]\n      begin\n        uri = URI.parse(resource[:source])\n      rescue => detail\n        self.fail Puppet::Error, _(\"Invalid source '%{uri}': %{detail}\") % { uri: uri, detail: detail }, detail\n      end\n\n      case uri.scheme\n      when nil\n        # no URI scheme => interpret the source as a local file\n        command_options << resource[:source]\n      when /file/i\n        command_options << uri.path\n      when 'puppet'\n        # we don't support puppet:// URLs (yet)\n        raise Puppet::Error, _('puppet:// URLs are not supported as gem sources')\n      else\n        # interpret it as a gem repository\n        command_options << '--source' << resource[:source].to_s << resource[:name]\n      end\n    else\n      command_options << resource[:name]\n    end\n\n    output = puppetservercmd(command_options)\n    # Apparently, some gem versions don't exit non-0 on failure.\n    self.fail _(\"Could not install: %{output}\") % { output: output.chomp } if output.include?('ERROR')\n  end\n\n  def uninstall\n    command_options = %w[gem uninstall]\n    command_options << '--executables' << '--all' << resource[:name]\n    command_options += uninstall_options if resource[:uninstall_options]\n","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/provider/package/puppetserver_gem.rb#L89-L125","documentation":"puppetserver_gem's install parses resource[:source] as a URI and explicitly rejects the 'puppet://' scheme - gems cannot be fetched from Puppet's fileserver. The error is raised before any gem command runs, so it is purely a manifest configuration error, not an execution failure.","triggerScenarios":"package { 'x': provider => puppetserver_gem, source => 'puppet:///modules/gems/x-1.0.gem' } - URI.parse yields scheme 'puppet' and the case at lib/puppet/provider/package/puppetserver_gem.rb:105 raises immediately.","commonSituations":"Users assuming package sources behave like file resource sources; copying puppet:// patterns that work for rpm/deb file sources; module examples reusing module-path URLs for gems.","solutions":["Serve the .gem over HTTP(S) or from a local path and point source at that: source => '/opt/gems/x-1.0.gem' or 'https://mirror.example/gems'","If the gem must come from the module, stage it with a file resource to a local path first, then reference that path as the package source with require =>","Drop the source attribute entirely to install from the default gem repositories"],"exampleFix":"// before\npackage { 'json-jruby':\n  ensure   => '1.8.3',\n  provider => puppetserver_gem,\n  source   => 'puppet:///modules/profile/gems/json-1.8.3.gem',\n}\n// after - stage the gem locally, then install from the file path\nfile { '/opt/gems/json-1.8.3.gem':\n  ensure => file,\n  source => 'puppet:///modules/profile/gems/json-1.8.3.gem',\n}\npackage { 'json-jruby':\n  ensure   => '1.8.3',\n  provider => puppetserver_gem,\n  source   => '/opt/gems/json-1.8.3.gem',\n  require  => File['/opt/gems/json-1.8.3.gem'],\n}","handlingStrategy":"validation","validationCode":"require 'uri'\n# Ruby: reject sources the puppetserver_gem provider cannot use, before catalog application\ndef supported_gem_source?(source)\n  scheme = URI.parse(source).scheme\n  scheme.nil? || scheme =~ /\\Afile\\z/i || %w[http https].include?(scheme)\nrescue URI::InvalidURIError\n  false\nend","typeGuard":"# Narrows a source string to the shapes puppetserver_gem accepts (local path, file://, http(s)://)\nGEM_SOURCE_SHAPE = %r{\\A(/|file://|https?://)}\ndef gem_source?(value)\n  value.is_a?(String) && !value.start_with?('puppet://') && GEM_SOURCE_SHAPE.match?(value)\nend","tryCatchPattern":"begin\n  provider.install\nrescue Puppet::Error => e\n  raise unless e.message =~ /puppet:\\/\\/ URLs are not supported/\n  raise Puppet::Error, \"#{resource[:name]}: stage the gem locally (file resource) instead of puppet://\"\nend","preventionTips":["Never use puppet:// URLs as package sources for gem providers","Standardize gem delivery: stage files to a local path or serve from an internal mirror","Add spec tests asserting source schemes on every package resource that sets one"],"tags":["puppetserver","gems","source-url","unsupported-scheme","manifest-config"],"backgroundTag":"unsupported-url-scheme","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}