{"record":{"id":"b5182bea2ce6c600","repo":"puppetlabs/puppet","slug":"no-more-routes-to-name","errorCode":null,"errorMessage":"No more routes to #{name}","messagePattern":"No more routes to #(.+?)","errorType":"exception","errorClass":"Puppet::HTTP::RouteError","httpStatus":null,"severity":"critical","filePath":"lib/puppet/http/session.rb","lineNumber":79,"sourceCode":"    cached = @resolved_services[name]\n    return cached if cached\n\n    canceled = false\n    canceled_handler = ->(cancel) { canceled = cancel }\n\n    @resolvers.each do |resolver|\n      Puppet.debug(\"Resolving service '#{name}' using #{resolver.class}\")\n      service = resolver.resolve(self, name, ssl_context: ssl_context, canceled_handler: canceled_handler)\n      if service\n        @resolved_services[name] = service\n        Puppet.debug(\"Resolved service '#{name}' to #{service.url}\")\n        return service\n      elsif canceled\n        break\n      end\n    end\n\n    raise Puppet::HTTP::RouteError, \"No more routes to #{name}\"\n  end\n\n  # Collect per-site server versions. This will allow us to modify future\n  # requests based on the version of puppetserver we are talking to.\n  #\n  # @param [Puppet::HTTP::Response] response the request response containing headers\n  #\n  # @api private\n  def process_response(response)\n    version = response[Puppet::HTTP::HEADER_PUPPET_VERSION]\n    if version\n      site = Puppet::HTTP::Site.from_uri(response.url)\n      @server_versions[site] = version\n    end\n  end\n\n  # Determine if a session supports a capability. Depending on the server version\n  # we are talking to, we know certain features are available or not. These","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/http/session.rb#L61-L97","documentation":"After the session walks its resolver chain (SRV record resolver, then server_list resolver) without any resolver producing a usable service, it raises Puppet::HTTP::RouteError. This is the terminal failure of service discovery: no explicit URL was given, nothing was cached, and every configured discovery mechanism came up empty.","triggerScenarios":"dns_srv_domain is set and the SRV lookup yields no usable records while server_list is empty or all its entries fail their probe; every host:port candidate in server_list is unreachable (refused/timeout on 8140); the explicit url: bypass was not used.","commonSituations":"Wrong or stale server_list in puppet.conf; load balancer VIP down; firewall blocking TCP 8140; DNS SRV records (_x-puppet._tcp) deleted while dns_srv_domain remains set; TLS probe of each candidate failing during bootstrap before certificates are issued.","solutions":["Run with --debug and read the 'Resolving service ... using' lines, then verify each candidate host:port is reachable (curl -k https://server:8140/status/v1/simple)","Fix or remove dns_srv_domain and correct server_list so at least one route is valid","Bypass discovery for one-offs by passing url: to route_to (explicit host and port skips resolvers)","If a firewall or NAT is involved, open TCP 8140 to every master in server_list before retrying"],"exampleFix":"# before: dns_srv_domain = example.com with no SRV records, no server_list\nsession.route_to(:puppet) # => Puppet::HTTP::RouteError: No more routes to puppet\n\n# after: puppet.conf -> server_list = puppet1.example.com,puppet2.example.com\nsession.route_to(:puppet)\n# or explicit bypass (ruby):\nsession.route_to(:puppet, url: URI('https://puppet1.example.com:8140'))","handlingStrategy":"try-catch","validationCode":"# ruby\nrequire 'socket'\nreachable = Puppet[:server_list].split(',').any? do |h|\n  begin\n    TCPSocket.new(h.strip, Puppet[:serverport]).tap(&:close); true\n  rescue StandardError\n    false\n  end\nend\nraise 'no puppetserver reachable' unless reachable","typeGuard":"def explicit_route?(url)\n  url.is_a?(URI) && !url.host.nil? && !url.host.empty?\nend","tryCatchPattern":"begin\n  service = session.route_to(:puppet)\nrescue Puppet::HTTP::RouteError => e\n  Puppet.err(e.message)\n  service = session.route_to(:puppet, url: KNOWN_MASTER_URI)  # explicit fallback\nend","preventionTips":["Keep server_list accurate and list more than one master for resilience","Smoke-test TCP 8140 to each master during bootstrap; do not rely on SRV alone","Pass an explicit url: to route_to in one-off scripts to bypass discovery","Watch 'Resolving service' debug lines in integration tests to catch discovery regressions"],"tags":["puppet-http","service-discovery","route-error","network","srv-records"],"backgroundTag":"service-discovery-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}