{"record":{"id":"31f36efb24e28489","repo":"puppetlabs/puppet","slug":"unable-to-read-overrides-plist-too-many-attempts","errorCode":null,"errorMessage":"Unable to read overrides plist, too many attempts","messagePattern":"Unable to read overrides plist, too many attempts","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/provider/service/launchd.rb","lineNumber":215,"sourceCode":"    end\n    @job_list\n  end\n\n  # Read a plist, whether its format is XML or in Apple's \"binary1\"\n  # format.\n  def self.read_plist(path)\n    Puppet::Util::Plist.read_plist_file(path)\n  end\n\n  # Read overrides plist, retrying if necessary\n  def self.read_overrides\n    i = 1\n    overrides = nil\n    loop do\n      Puppet.debug(_(\"Reading overrides plist, attempt %{i}\") % { i: i }) if i > 1\n      overrides = read_plist(launchd_overrides)\n      break unless overrides.nil?\n      raise Puppet::Error, _('Unable to read overrides plist, too many attempts') if i == 20\n\n      Puppet.info(_('Overrides file could not be read, trying again.'))\n      Kernel.sleep(0.1)\n      i += 1\n    end\n    overrides\n  end\n\n  # Clean out the @property_hash variable containing the cached list of services\n  def flush\n    @property_hash.clear\n  end\n\n  def exists?\n    Puppet.debug(\"Puppet::Provider::Launchd:Ensure for #{@property_hash[:name]}: #{@property_hash[:ensure]}\")\n    @property_hash[:ensure] != :absent\n  end\n","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/provider/service/launchd.rb#L197-L233","documentation":"The launchd provider reads the launchd overrides plist (the path returned by launchd_overrides, e.g. /var/db/launchd.db/com.apple.launchd/overrides.plist) through Puppet::Util::Plist. read_plist returns nil when the file cannot be parsed; read_overrides retries up to 20 times with a 0.1s sleep (~2 seconds total) and raises when every attempt yields nil.","triggerScenarios":"self.read_overrides is called during prefetch/flush of launchd services when the overrides file is missing, empty, or not a valid plist (XML or binary1), so Puppet::Util::Plist.read_plist_file keeps returning nil across all 20 attempts.","commonSituations":"Freshly imaged Macs that never generated an overrides file; the plist corrupted by a bad write or truncated sync tool; macOS upgrades relocating the database; configuration-management tools other than Puppet having clobbered the file.","solutions":["Verify the file exists at the path in the error's context: ls -l /var/db/launchd.db/com.apple.launchd/","Validate the plist: plutil -lint on the overrides file","Restore a known-good copy from backup/TM snapshot, or let launchd regenerate it by toggling a job's disabled state once interactively","Check permissions/ownership (root:wheel, readable) so the agent-side parse succeeds"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"plutil -lint /var/db/launchd.db/com.apple.launchd/overrides.plist \\\n  || echo \"overrides plist invalid — restore before puppet run\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add a plutil -lint check to your macOS baseline/acceptance script for launchd-managed fleets","Exclude /var/db/launchd.db from sync tools that can truncate binary plists","Monitor for repeated 'Overrides file could not be read, trying again.' info messages — they precede the fatal 20th attempt"],"tags":["puppet","launchd","macos","plist","retry-exhausted"],"backgroundTag":"plist-parse-failure","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}