{"record":{"id":"dedde14c8be87e2f","repo":"puppetlabs/puppet","slug":"request-to-puppet-forge-failed-detail-detail","errorCode":null,"errorMessage":"Request to Puppet Forge failed. Detail: %{detail}.","messagePattern":"Request to Puppet Forge failed\\. Detail: %(.+?)\\.","errorType":"http","errorClass":"Puppet::Forge::Errors::ResponseError","httpStatus":null,"severity":"critical","filePath":"lib/puppet/forge.rb","lineNumber":75,"sourceCode":"  # @raise [Puppet::Forge::Errors::ResponseError] if the repository returns a\n  #   bad HTTP response\n  def search(term)\n    matches = []\n    uri = \"/v3/modules?query=#{term}\"\n    if Puppet[:module_groups]\n      uri += \"&module_groups=#{Puppet[:module_groups].tr('+', ' ')}\"\n    end\n\n    while uri\n      # make_http_request URI encodes parameters\n      response = make_http_request(uri)\n\n      if response.code == 200\n        result = Puppet::Util::Json.load(response.body)\n        uri = decode_uri(result['pagination']['next'])\n        matches.concat result['results']\n      else\n        raise ResponseError.new(:uri => response.url, :response => response)\n      end\n    end\n\n    matches.each do |mod|\n      mod['author'] = mod['owner']['username']\n      mod['tag_list'] = mod['current_release']['tags']\n      mod['full_name'] = \"#{mod['author']}/#{mod['name']}\"\n      mod['version'] = mod['current_release']['version']\n      mod['project_url'] = mod['homepage_url']\n      mod['desc'] = mod['current_release']['metadata']['summary'] || ''\n    end\n  end\n\n  # Fetches {ModuleRelease} entries for each release of the named module.\n  #\n  # @param input [String] the module name to look up\n  # @return [Array<SemanticPuppet::Dependency::ModuleRelease>] a list of releases for\n  #         the given name","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/forge.rb#L57-L93","documentation":"Puppet's SSL state machine enters the Wait state when the agent has submitted a CSR but holds no signed certificate. waitforcert sets the sleep between checks; when it is below 1 the agent is not allowed to wait at all, so next_state logs this error and calls exit(1). This is the default for one-time runs (puppet agent --test / --onetime), so the first run of a new agent against a CA with manual signing exits immediately after submitting its CSR.","triggerScenarios":"Running puppet agent --test (or --onetime) before the CA has signed the node's certificate; waitforcert = 0 in puppet.conf while a CSR is pending; a CSR resubmitted after puppetserver ca clean on a node doing one-time runs. The exit happens on the first Wait transition, before any sleeping.","commonSituations":"New node bootstraps against a CA with autosigning disabled; CI pipelines that run puppet agent -t before an operator signs; container images that run Puppet once at startup and exit when no certificate is ready.","solutions":["Sign the request on the CA: puppetserver ca sign --certname <certname> (puppet cert sign <certname> on legacy masters), then rerun the agent.","If signing takes time, allow the agent to wait instead: puppet agent --test --waitforcert 30.","Confirm the CSR actually arrived: <ssldir>/certificate_requests/<certname>.pem exists locally and puppetserver ca list shows it on the master.","For fleets or short-lived nodes, enable autosigning (autosign.conf or a policy executable) so certificates exist by the first agent run.","If the CSR required dns_alt_names, clean and resubmit with --dns_alt_names; a name mismatch means the CA never returns a certificate."],"exampleFix":"# before: one-time run with default waitforcert=0 exits as soon as the CSR is unsigned\npuppet agent --test\n\n# after: poll every 30 seconds (bounded by maxwaitforcert) instead of exiting\npuppet agent --test --waitforcert 30\n# or sign on the CA first:\n#   puppetserver ca sign --certname web01.example.com","handlingStrategy":"validation","validationCode":"# Pre-flight: only run a one-time agent when the signed cert already exists\nssldir=$(puppet config print ssldir)\ncertname=$(puppet config print certname)\nif [ ! -f \"$ssldir/certs/$certname.pem\" ]; then\n  echo \"CSR not signed yet - run: puppetserver ca sign --certname $certname\" >&2\n  exit 1\nfi\npuppet agent --onetime","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In automation, gate puppet agent --test on the existence of $ssldir/certs/$certname.pem and surface a sign request instead of letting the agent exit 1.","Pass --waitforcert N in bootstrap scripts; never rely on the implicit 0 default of one-time runs.","Treat agent exit code 1 from a first run as a provisioning signal (sign the cert), not a catalog failure."],"tags":["puppet","ssl","certificate","csr","waitforcert","agent","exit-code"],"backgroundTag":"pending-certificate-signing","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}