ruby/ruby · error · ArgumentError
multiple proxy options specified
Error message
multiple proxy options specified
What it means
OpenURI.open_loop builds proxy settings from the options hash and allows at most one proxy selector: :proxy or :proxy_http_basic_authentication. If both keys are present it raises ArgumentError 'multiple proxy options specified' because the two mechanisms would fight over which proxy (and whose credentials) to use.
Source
Thrown at lib/open-uri.rb:191
ensure
if io.respond_to? :close!
io.close! # Tempfile
else
io.close if !io.closed?
end
end
else
io
end
end
def OpenURI.open_loop(uri, options) # :nodoc:
proxy_opts = []
proxy_opts << :proxy_http_basic_authentication if options.include? :proxy_http_basic_authentication
proxy_opts << :proxy if options.include? :proxy
proxy_opts.compact!
if 1 < proxy_opts.length
raise ArgumentError, "multiple proxy options specified"
end
case proxy_opts.first
when :proxy_http_basic_authentication
opt_proxy, proxy_user, proxy_pass = options.fetch(:proxy_http_basic_authentication)
proxy_user = proxy_user.to_str
proxy_pass = proxy_pass.to_str
if opt_proxy == true
raise ArgumentError.new("Invalid authenticated proxy option: #{options[:proxy_http_basic_authentication].inspect}")
end
when :proxy
opt_proxy = options.fetch(:proxy)
proxy_user = nil
proxy_pass = nil
when nil
opt_proxy = true
proxy_user = nil
proxy_pass = nil
endView on GitHub (pinned to 0e5b888e1c)
Solutions
- Keep exactly one proxy option; drop the other key from the merged hash before calling URI.open
- For authenticated proxies, use only :proxy_http_basic_authentication: [URI('http://proxy:8080'), user, pass]
- Or embed credentials in the proxy URI passed to :proxy — open-uri parses proxy userinfo (proxy_uri.userinfo.split(':')) — e.g. proxy: URI('http://user:pass@proxy:8080')
Example fix
# before
URI.open(url,
proxy: ENV['http_proxy'],
proxy_http_basic_authentication: [URI('http://proxy:8080'), 'u', 'p'])
# => ArgumentError: multiple proxy options specified
# after
URI.open(url, proxy: URI('http://u:p@proxy:8080')) Defensive patterns
Strategy: validation
Validate before calling
proxy_keys = %i[proxy proxy_http_basic_authentication].count { |k| options.include?(k) }
raise ArgumentError, 'multiple proxy options specified' if proxy_keys > 1
URI.open(url, **options) Prevention
- Choose one proxy mechanism for the whole app; embed credentials in the proxy URI if you use :proxy
- When merging option hashes from multiple layers, resolve proxy config last and keep a single key
- Delete the unused proxy key rather than letting it ride along in defaults
When it happens
Trigger: URI.open(url, proxy: ENV['http_proxy'], proxy_http_basic_authentication: [proxy_uri, user, pass]). Gem/application layers each merging their own proxy config into one options hash; env-based proxy detection combined with explicit authenticated-proxy credentials.
Common situations: A library auto-detects ENV['http_proxy'] via :proxy while application code also passes authenticated proxy credentials; layered HTTP wrappers deep-merging default options with call options, both sides adding a proxy key.
Related errors
- unrecognized option: #{k}
- encoding specified twice
- Invalid request_specific_fields option: #{options[:request_s
- userinfo not supported. [RFC3986]
- no filename: #{self.inspect}
AI-assisted analysis of ruby/ruby@0e5b888e1c (2026-08-21).
Data as JSON: /api/errors/8a596231e03ed078.
Report an issue: GitHub.