puppetlabs/puppet · error · Puppet::HTTP::TooManyRedirects
Too many HTTP redirections for %{addr}
Error message
Too many HTTP redirections for %{addr} What it means
Puppet::HTTP::Client follows 301/302/307 redirects through Puppet::HTTP::Redirector, counting each hop. When the hop count reaches the redirect limit — default 10, overridable per request via options[:redirect_limit] (client.rb:354) — it raises Puppet::HTTP::TooManyRedirects with the request URI in the message. This indicates a chain longer than allowed or a redirect loop.
Source
Thrown at lib/puppet/http/redirector.rb:46
when 301, 302, 307
true
else
false
end
end
# Implement the HTTP request redirection
#
# @param [Net::HTTP] request request that has been redirected
# @param [Puppet::HTTP::Response] response
# @param [Integer] redirects the current number of redirects
#
# @return [Net::HTTP] A new request based on the original request, but with
# the redirected location
#
# @api private
def redirect_to(request, response, redirects)
raise Puppet::HTTP::TooManyRedirects, request.uri if redirects >= @redirect_limit
location = parse_location(response)
url = request.uri.merge(location)
new_request = request.class.new(url)
new_request.body = request.body
request.each do |header, value|
unless Puppet[:location_trusted]
# skip adding potentially sensitive header to other hosts
next if header.casecmp('Authorization').zero? && request.uri.host.casecmp(location.host) != 0
next if header.casecmp('Cookie').zero? && request.uri.host.casecmp(location.host) != 0
end
# Allow Net::HTTP to set its own Accept-Encoding header to avoid errors with HTTP compression.
# See https://github.com/puppetlabs/puppet/issues/9143
next if header.casecmp('Accept-Encoding').zero?
new_request[header] = value
endView on GitHub (pinned to e227c27540)
Solutions
- Reproduce with curl -ILv <url> and count the hops: fix the server-side rewrite loop first.
- Ensure redirect targets are final URLs (correct scheme/host/port) rather than re-entering the redirect rule.
- If the chain is legitimately longer than 10, raise options[:redirect_limit] on the specific request instead of globally.
- Check proxy PreserveHost/redirect rules when a load balancer sits in front of the compiler/CA.
Example fix
# before
response = client.get(uri)
# after - allow a longer (but still bounded) chain for this request
response = client.get(uri, options: { redirect_limit: 20 }) Defensive patterns
Strategy: try-catch
Try / catch
begin
response = client.get(uri)
rescue Puppet::HTTP::TooManyRedirects => e
# e.message includes the original request URI
Puppet.err "redirect budget exhausted for #{uri}; verify server/proxy rewrites"
raise
end Prevention
- Verify redirect chains with curl -IL before pointing puppet at a URL.
- Keep the default redirect_limit of 10; fix loops server-side instead of raising it.
- Configure proxies with final target URLs (correct scheme/host/port) to avoid re-entry.
When it happens
Trigger: A redirect chain (A→B→C…) longer than redirect_limit; a loop such as https→https rewrites where hostnames alternate; a proxy redirecting to itself; count reaches the limit on the next redirect_to call because redirects >= @redirect_limit.
Common situations: Misconfigured reverse proxy or SSL terminator rewriting in a circle; CDN/LB redirect rules that drop the port; server_list entries pointing at a vhost that redirects to a login page that redirects back; captive portals.
Related errors
- Location response header is missing
- Could not back up %{file}: %{detail}
- 'put' requires a string 'body' argument
- 'put' requires a 'content-type' header
- 'post' requires a string 'body' argument
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/c10f27f0145c4ba8.
Report an issue: GitHub.