{"record":{"id":"5be30722da2bec41","repo":"puppetlabs/puppet","slug":"could-not-select-a-functional-puppet-server-from-s","errorCode":null,"errorMessage":"Could not select a functional puppet server from server_list: '%{server_list}'","messagePattern":"Could not select a functional puppet server from server_list: '%(.+?)'","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/puppet/configurer.rb","lineNumber":329,"sourceCode":"    completed = nil\n    begin\n      # Skip failover logic if the server_list setting is empty\n      do_failover = Puppet.settings[:server_list] && !Puppet.settings[:server_list].empty?\n\n      # When we are passed a catalog, that means we're in apply\n      # mode. We shouldn't try to do any failover in that case.\n      if options[:catalog].nil? && do_failover\n        server, port = find_functional_server\n        if server.nil?\n          detail = _(\"Could not select a functional puppet server from server_list: '%{server_list}'\") % { server_list: Puppet.settings.value(:server_list, Puppet[:environment].to_sym, true) }\n          if Puppet[:usecacheonfailure]\n            options[:pluginsync] = false\n            @running_failure = true\n\n            server = Puppet[:server_list].first[0]\n            port = Puppet[:server_list].first[1] || Puppet[:serverport]\n\n            Puppet.err(detail)\n          else\n            raise Puppet::Error, detail\n          end\n        else\n          # TRANSLATORS 'server_list' is the name of a setting and should not be translated\n          Puppet.debug _(\"Selected puppet server from the `server_list` setting: %{server}:%{port}\") % { server: server, port: port }\n          report.server_used = \"#{server}:#{port}\"\n        end\n        Puppet.override(server: server, serverport: port) do\n          completed = run_internal(options)\n        end\n      else\n        completed = run_internal(options)\n      end\n    ensure\n      # we may sleep for awhile, close connections now\n      Puppet.runtime[:http].close\n    end","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/configurer.rb#L311-L347","documentation":"Raised (or logged) by Puppet::Configurer after find_functional_server probed every entry in server_list and none answered. When usecacheonfailure is true the agent degrades: pluginsync is disabled, the first server in the list is selected, and a cached catalog is used. Otherwise Puppet::Error stops the run.","triggerScenarios":"A catalog run with options[:catalog] nil and failover active, where every 'host[:port]' in server_list fails the liveness probe: puppetserver down, 8140 blocked by firewall, DNS resolving wrong, TLS rejected, or server_list formatted so the entries are unusable.","commonSituations":"Puppet server stopped after an upgrade; load balancer drained; security group closed 8140; typo'd server_list such as 'puppet:puppet2' instead of comma-separated entries; IPv6/IPv4 resolution differences.","solutions":["Verify each entry responds: `curl -k https://<host>:8140/status/v1/simple`","Check server_list syntax — comma-separated, optional :port per entry — via `puppet config print server_list`","Start/restart puppetserver on the listed hosts and inspect its logs","Open TCP 8140 in firewalls and fix DNS for every listed host","If degraded mode is intended, confirm usecacheonfailure=true so cached catalogs carry the run"],"exampleFix":"# before (puppet.conf)\nserver_list = puppet:puppet2\n\n# after\nserver_list = puppet.example.com:8140,puppet2.example.com:8140","handlingStrategy":"validation","validationCode":"require 'socket'\n\nPuppet[:server_list].each do |host, port|\n  port ||= Puppet[:serverport]\n  begin\n    TCPSocket.new(host, port).close\n  rescue SystemCallError, IOError\n    warn \"#{host}:#{port} unreachable\"\n  end\nend","typeGuard":null,"tryCatchPattern":"begin\n  Puppet::Configurer.new(node).run\nrescue Puppet::Error => e\n  raise unless e.message.include?('functional puppet server')\n  report_all_servers_down   # surface which entries failed; cached catalog may already be in use\nend","preventionTips":["Monitor TCP 8140 and /status/v1/simple on every server_list entry","Lint server_list format in config CI (comma-separated host[:port])","Decide deliberately whether usecacheonfailure should carry runs during outages"],"tags":["ruby","puppet","network","failover","server-list","high-availability"],"backgroundTag":"server-failover-exhausted","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}