{"record":{"id":"63df7e1556877c66","repo":"puppetlabs/puppet","slug":"unable-to-verify-the-ssl-certificate-at-uri","errorCode":null,"errorMessage":"Unable to verify the SSL certificate at %{uri}","messagePattern":"Unable to verify the SSL certificate at %(.+?)","errorType":"http","errorClass":"Puppet::Forge::Errors::SSLVerifyError","httpStatus":null,"severity":"error","filePath":"lib/puppet/forge/repository.rb","lineNumber":54,"sourceCode":"        str = @uri.to_s\n        str.chomp!('/')\n        str += Puppet::Util.uri_encode(path)\n        uri = URI(str)\n\n        headers = { \"User-Agent\" => user_agent }\n\n        if forge_authorization\n          uri.user = nil\n          uri.password = nil\n          headers[\"Authorization\"] = forge_authorization\n        end\n\n        http = Puppet.runtime[:http]\n        response = http.get(uri, headers: headers, options: { ssl_context: @ssl_context })\n        io.write(response.body) if io.respond_to?(:write)\n        response\n      rescue Puppet::SSL::CertVerifyError => e\n        raise SSLVerifyError.new(:uri => @uri.to_s, :original => e.cause)\n      rescue => e\n        raise CommunicationError.new(:uri => @uri.to_s, :original => e)\n      end\n    end\n\n    def forge_authorization\n      if Puppet[:forge_authorization]\n        Puppet[:forge_authorization]\n      elsif Puppet.features.pe_license?\n        PELicense.load_license_key.authorization_token\n      end\n    end\n\n    # Return the local file name containing the data downloaded from the\n    # repository at +release+ (e.g. \"myuser-mymodule\").\n    def retrieve(release)\n      path = @host.chomp('/') + release\n      cache.retrieve(path)","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/forge/repository.rb#L36-L72","documentation":"When a resource receives events through notify/subscribe relationships, the transaction's event manager calls resource.send(callback) on it (normally :refresh). If that callback raises - a service provider whose restart command fails, an exec whose refreshed command exits non-zero, a provider without restart support - this rescue logs Failed to call refresh with the original exception message, marks the resource status failed_to_restart, records a failed status event, and returns false so the transaction continues with other resources. The full backtrace goes to the resource's log_exception output, visible at debug/trace level.","triggerScenarios":"File->Service subscribe where the notified systemctl restart fails because the same run shipped a broken config; Service with restart => '<cmd>' where the command is absent or returns non-zero; providers whose refresh path raises (unsupported restart, missing init system in containers); Mount reload failing on notify; Exec with refreshonly whose command fails only when triggered.","commonSituations":"Templates that deploy a syntactically invalid app/nginx config and immediately restart the service; minimal containers where service restart commands do not exist; custom in-house types whose provider never implemented refresh or restart.","solutions":["Reproduce the refresh by hand as root (systemctl restart nginx; nginx -t) - whatever fails there is the %{detail}.","Run puppet agent -t --debug (or --trace) and read the log_exception backtrace printed next to this message to identify the failing provider call.","Fix the underlying cause: repair the config/template the restart depends on, or install the missing command/init support.","If restart genuinely cannot work on the platform, redirect refresh to something safe: restart => '/usr/sbin/nginx -s reload', or hasrestart => false so refresh falls back to stop/start.","For your own types, implement refresh (and the restart/stop/start it delegates to) instead of letting the default raise."],"exampleFix":"# before: notified restart of a service whose restart command fails -> Failed to call 'refresh'\nservice { 'nginx':\n  ensure    => running,\n  subscribe => File['/etc/nginx/nginx.conf'],\n}\n\n# after: refresh path validates config and reloads, so the callback cannot raise on bad config\nservice { 'nginx':\n  ensure    => running,\n  subscribe => File['/etc/nginx/nginx.conf'],\n  restart   => '/usr/sbin/nginx -t && /bin/systemctl reload nginx',\n}","handlingStrategy":"try-catch","validationCode":"# Spec: prove the callback the event manager will invoke cannot raise\nit 'survives the refresh callback' do\n  svc = Puppet::Type.type(:service).new(\n    name: 'nginx', ensure: :running, provider: :systemd\n  )\n  expect { svc.provider.refresh }.not_to raise_error\nend","typeGuard":null,"tryCatchPattern":"# Provider authors: guard the callback so the event manager never sees a raise\ndef refresh\n  return unless resource.should(:ensure) == :running  # no restart while stopped\n  systemctl('reload-or-restart', resource[:name])\nrescue Puppet::ExecutionFailure => e\n  # Narrow rescue only: report and keep the provider consistent\n  warning(\"restart failed: #{e}\")\n  nil\nend","preventionTips":["Smoke-test the restart command manually on every node class that receives notify/subscribe events.","Validate generated configs before the service reloads (an Exec running nginx -t with refreshonly, subscribed to by the service).","In test runs, assert resource statuses contain no failed_to_restart entries - that flag is how this rescue is visible in reports.","Implement refresh explicitly in custom providers; the default raises when restart is unsupported."],"tags":["puppet","catalog","event","refresh","notify","subscribe","provider","service"],"backgroundTag":"resource-refresh-callback-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}