jnunemaker/httparty · error · HTTParty::UnsupportedURIScheme

'#{new_uri}' Must be HTTP, HTTPS or Generic

Error message

'#{new_uri}' Must be HTTP, HTTPS or Generic

What it means

HTTParty raises UnsupportedURIScheme when the fully-built request URI's scheme is not in SupportedURISchemes (['http', 'https', 'webcal', nil] — nil meaning a scheme-less generic/relative URI). The check happens after the query string is attached, on every non-redirect request. The message names HTTP, HTTPS and Generic; webcal is also accepted. ftp://, file://, data:// and other schemes are rejected before any socket is opened.

Source

Thrown at lib/httparty/request.rb:124

      end

      if path.relative? && path.host
        new_uri = options[:uri_adapter].parse("#{@last_uri.scheme}:#{path}").normalize
      elsif path.relative?
        new_uri = options[:uri_adapter].parse("#{base_uri}#{path}").normalize
      else
        new_uri = path.clone
      end

      validate_uri_safety!(new_uri) unless redirect

      # avoid double query string on redirects [#12]
      unless redirect
        new_uri.query = query_string(new_uri)
      end

      unless SupportedURISchemes.include? new_uri.scheme
        raise UnsupportedURIScheme, "'#{new_uri}' Must be HTTP, HTTPS or Generic"
      end

      @last_uri = new_uri
    end

    def base_uri
      if redirect
        base_uri = "#{@last_uri.scheme}://#{@last_uri.host}"
        base_uri = "#{base_uri}:#{@last_uri.port}" if @last_uri.port != 80
        base_uri
      else
        options[:base_uri] && HTTParty.normalize_base_uri(options[:base_uri])
      end
    end

    def format
      options[:format] || (format_from_mimetype(last_response['content-type']) if last_response)
    end

View on GitHub (pinned to 8f4a09e343)

Solutions

  1. Use http:// or https:// for the base_uri and absolute paths.
  2. For webcal endpoints, keep the webcal scheme (it is supported) or convert it to http(s) explicitly.
  3. Download ftp/file resources with Net::FTP/File.read instead of HTTParty.

Example fix

# before
class Files
  include HTTParty
  base_uri 'ftp://files.example.com'
end
Files.get('/data.csv')   # UnsupportedURIScheme

# after
base_uri 'https://files.example.com'
Defensive patterns

Strategy: validation

Validate before calling

uri = URI.parse(url.to_s)
unless %w[http https webcal].include?(uri.scheme) || uri.scheme.nil?
  raise HTTParty::UnsupportedURIScheme, "#{uri.scheme} not supported"
end
Foo.get(uri)

Type guard

supported_scheme = ->(u) { scheme = URI.parse(u.to_s).scheme; scheme.nil? || %w[http https webcal].include?(scheme) }

Try / catch

begin
  Foo.get(url)
rescue HTTParty::UnsupportedURIScheme
  raise ArgumentError, "only http/https (webcal) targets are fetchable: #{url}"
end

Prevention

When it happens

Trigger: `Foo.get('ftp://files.example.com/data.csv')`, `base_uri 'file:///var/www'`, a response Location header pointing at a non-HTTP scheme while following redirects, or a URI built by joining a base_uri like 'example.com' with a path that resolves to an unexpected scheme.

Common situations: Feeds discovered from RSS/webcal links, config-driven base_uri values that accidentally include a scheme prefix like 'ftp://' or 'socket://', and tests stubbing URLs with fake schemes.

Related errors


AI-assisted analysis of jnunemaker/httparty@8f4a09e343 (2026-08-21). Data as JSON: /api/errors/d67095f4dad1ff5d. Report an issue: GitHub.