jnunemaker/httparty · error · ArgumentError

only one authentication method, :basic_auth or :digest_auth

Error message

only one authentication method, :basic_auth or :digest_auth may be used at a time

What it means

Request#validate raises ArgumentError when both options[:basic_auth] and options[:digest_auth] are present on the same request. HTTParty cannot apply two WWW-Authenticate schemes at once and refuses to risk sending credentials computed for the wrong challenge. The conflict can come from a single call or from class-level defaults merging with per-request options.

Source

Thrown at lib/httparty/request.rb:418

      options[:headers] ||= {}
      options[:headers]['Cookie'] = cookies_hash.to_cookie_string
    end

    # Uses the HTTP Content-Type header to determine the format of the
    # response It compares the MIME type returned to the types stored in the
    # SupportedFormats hash
    def format_from_mimetype(mimetype)
      if mimetype && parser.respond_to?(:format_from_mimetype)
        parser.format_from_mimetype(mimetype)
      end
    end

    def validate
      raise HTTParty::RedirectionTooDeep.new(last_response), 'HTTP redirects too deep' if options[:limit].to_i <= 0
      raise ArgumentError, 'only get, post, patch, put, delete, head, and options methods are supported' unless SupportedHTTPMethods.include?(http_method)
      raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].respond_to?(:to_hash)
      raise ArgumentError, 'only one authentication method, :basic_auth or :digest_auth may be used at a time' if options[:basic_auth] && options[:digest_auth]
      raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].respond_to?(:to_hash)
      raise ArgumentError, ':digest_auth must be a hash' if options[:digest_auth] && !options[:digest_auth].respond_to?(:to_hash)
      raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].respond_to?(:to_hash)
    end

    def post?
      Net::HTTP::Post == http_method
    end

    def set_basic_auth_from_uri
      if path.userinfo
        username, password = path.userinfo.split(':')
        options[:basic_auth] = {username: username, password: password}
        @credentials_sent = true
      end
    end

    def decompress(body, encoding)

View on GitHub (pinned to 8f4a09e343)

Solutions

  1. Use exactly one auth type per request: remove the other key.
  2. If a base class sets basic_auth, override per-request with `basic_auth: nil`... instead restructure: clear defaults or use separate client classes.
  3. For endpoints with different schemes, split into two HTTParty classes (one basic, one digest).

Example fix

# before
class Base
  include HTTParty
  basic_auth 'u', 'p'
end
Base.get(url, digest_auth: { username: 'u', password: 'p' })  # ArgumentError

# after
class BasicClient
  include HTTParty
  basic_auth 'u', 'p'
end
class DigestClient
  include HTTParty
  digest_auth 'u', 'p'
end
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, 'use only one of basic_auth/digest_auth' if opts.key?(:basic_auth) && opts.key?(:digest_auth)
Foo.get(url, **opts)

Try / catch

begin
  Foo.get(url, **opts)
rescue ArgumentError => e
  raise unless e.message.include?('authentication method')
  opts = opts.except(:basic_auth)  # or :digest_auth, per target API
  retry
end

Prevention

When it happens

Trigger: `Foo.get(url, basic_auth: { username: u, password: p }, digest_auth: { username: u, password: p })`; class-level `basic_auth u, p` combined with a per-request `digest_auth:` option (defaults are deep-merged into request options); credentials extracted from a URI userinfo combined with an explicit digest_auth hash.

Common situations: Switching an API from Basic to Digest auth and leaving the old setting behind, shared client base classes setting basic_auth for all children while one endpoint needs digest, and copying both options from a provider's docs 'to be safe'.

Understand the failure class

Related errors


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