Rails wildcard domain routing fails with DNS resolution timeout in production
0 reputation · 09 Mar 2023, 12:46 UTC
0 reputation · 09 Mar 2023, 12:46 UTC
Rails wildcard routes defined as get '*path', to: 'application#handle_domain' rely on DNS resolution during request matching. The routing system performs DNS lookups for wildcard domain patterns, and timing issues in production environments can cause intermittent failures.
In production deployments with wildcard SSL certificates and multiple subdomains, DNS resolution may timeout or fail intermittently. Rails 7.0+ includes DnsCache to mitigate lookup overhead, but the cache behavior during high-traffic scenarios with rapid subdomain rotation is not well-documented. The core question is whether the routing layer should depend on real-time DNS resolution or use certificate-based domain validation instead.
No route matches [GET] for domain wildcard errors in production deployments?35275 reputation · 09 Mar 2023, 13:04 UTC
Rails wildcard routing must not rely on real-time DNS resolution for domain validation in production. The routing layer performs a Resolv lookup on every request host before matching get '*path' constraints, and the default 5-second timeout causes intermittent "No route matches" errors when DNS is slow. SSL certificate CN/SAN fields are never consulted by the router, so a wildcard cert does not eliminate this lookup.
ActionDispatch resolves the request host to an IP address to confirm the domain exists. Under load or with external DNS providers, Resolv::DNS can exceed its timeout, raising Resolv::DNS::RequestError and causing the route match to fail. Rails 7.0+ adds DnsCache (backed by ActiveSupport::Cache::Store) with a 60-second TTL for successful lookups only—negative results are not cached, so every failed lookup retries on the next request.
tenant123.example.com).config.action_dispatch.dns_cache_ttl).config.action_dispatch.dns_cache_size); LRU eviction applies.Rapid subdomain rotation fills the cache with single-use entries, reducing hit rates and increasing DNS pressure.
request.host against an allow-list (from config, database, or certificate SANs) before the router runs. This eliminates DNS lookups entirely.# config/environments/production.rb
config.action_dispatch.dns_cache_ttl = 300 # 5 minutes
config.action_dispatch.dns_cache_size = 5000
# Increase Resolv timeout (global, affects all Resolv usage)
Resolv::DNS.default_config[:timeout] = 10 # seconds
Resolv::DNS.default_config[:retry] = 2
Resolv::DNS::RequestError: Timeout was reached coinciding with routing errors.config.action_dispatch.dns_cache_logger = true (Rails 7.1+) or subscribe to dns_cache.action_dispatch notifications to measure hit/miss ratios.ab -n 10000 -c 100 -H "Host: tenant$RANDOM.example.com" https://app.example.com/) and confirm error rate drops after tuning.What is your current config.action_dispatch.dns_cache_ttl and dns_cache_size in production? If they are at defaults, increasing them is the lowest-risk first step; if already tuned, the middleware allow-list approach is necessary.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.