ruby/ruby · error · ArgumentError

not a domain name: #{other.inspect}

Error message

not a domain name: #{other.inspect}

What it means

Resolv::DNS::Name#subdomain_of? compares against another Name object and starts by asserting Name === other. Passing a plain String (or anything else) raises ArgumentError, because the method reads other.absolute? and other.to_a, which only exist on Name.

Source

Thrown at lib/resolv.rb:1354

      alias eql? == # :nodoc:

      ##
      # Returns true if +other+ is a subdomain.
      #
      # Example:
      #
      #   domain = Resolv::DNS::Name.create("y.z")
      #   p Resolv::DNS::Name.create("w.x.y.z").subdomain_of?(domain) #=> true
      #   p Resolv::DNS::Name.create("x.y.z").subdomain_of?(domain) #=> true
      #   p Resolv::DNS::Name.create("y.z").subdomain_of?(domain) #=> false
      #   p Resolv::DNS::Name.create("z").subdomain_of?(domain) #=> false
      #   p Resolv::DNS::Name.create("x.y.z.").subdomain_of?(domain) #=> false
      #   p Resolv::DNS::Name.create("w.z").subdomain_of?(domain) #=> false
      #

      def subdomain_of?(other)
        raise ArgumentError, "not a domain name: #{other.inspect}" unless Name === other
        return false if @absolute != other.absolute?
        other_len = other.length
        return false if @labels.length <= other_len
        return @labels[-other_len, other_len] == other.to_a
      end

      def hash # :nodoc:
        return @labels.hash ^ @absolute.hash
      end

      def to_a # :nodoc:
        return @labels
      end

      def length # :nodoc:
        return @labels.length
      end

View on GitHub (pinned to 0e5b888e1c)

Solutions

  1. Convert first: name.subdomain_of?(Resolv::DNS::Name.create("example.com"))
  2. Normalize at the boundary with a helper that coerces strings to Name and passes Name objects through
  3. Mind absolute vs relative names: Name.create("example.com") is relative; use a trailing dot ("example.com.") for FQDN semantics, or the answer is false rather than an error

Example fix

# before
Resolv::DNS::Name.create(req_host).subdomain_of?("corp.example.com")
# => ArgumentError: not a domain name: "corp.example.com"

# after
zone = Resolv::DNS::Name.create("corp.example.com")
Resolv::DNS::Name.create(req_host).subdomain_of?(zone)
Defensive patterns

Strategy: type-guard

Type guard

def to_dns_name(value)
  Resolv::DNS::Name === value ? value : Resolv::DNS::Name.create(value)
end

name.subdomain_of?(to_dns_name(user_host))

Prevention

When it happens

Trigger: name.subdomain_of?("example.com"); comparing against a host string received from HTTP params, config, or DB before conversion; calling subdomain_of? with a Name built by a different DNS library (e.g. Dnsruby::Name).

Common situations: Domain-allowlist checks in request validators; security code testing whether a user-supplied host falls under a corporate domain; mixing string domains and Name objects in the same code path.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


AI-assisted analysis of ruby/ruby@0e5b888e1c (2026-08-21). Data as JSON: /api/errors/128fd541410afb46. Report an issue: GitHub.