puppetlabs/puppet · error · Puppet::Error

Systemd stop for #{name} failed! journalctl log for #{name}:

Error message

Systemd stop for #{name} failed!
journalctl log for #{name}:
#{journalctl_output}

What it means

Raised by Puppet's systemd service provider when stopping a service fails. The `stop` method delegates to the base provider which executes `systemctl stop <name>`; a Puppet::Error from that call is re-raised with the last 50 journalctl lines for the unit. Typically the unit fails to stop within its TimeoutStopSec, or systemd cannot cleanly kill the process group.

Source

Thrown at lib/puppet/provider/service/systemd.rb:222

  def restart
    daemon_reload?
    super
  rescue Puppet::Error => e
    raise Puppet::Error, prepare_error_message(@resource[:name], 'restart', e)
  end

  def start
    daemon_reload?
    super
  rescue Puppet::Error => e
    raise Puppet::Error, prepare_error_message(@resource[:name], 'start', e)
  end

  def stop
    super
  rescue Puppet::Error => e
    raise Puppet::Error, prepare_error_message(@resource[:name], 'stop', e)
  end

  def prepare_error_message(name, action, exception)
    error_return = "Systemd #{action} for #{name} failed!\n"
    journalctl_command = "journalctl -n 50 --since '5 minutes ago' -u #{name} --no-pager"
    Puppet.debug("Running journalctl command to get logs for systemd #{action} failure: #{journalctl_command}")
    journalctl_output = execute(journalctl_command)
    error_return << "journalctl log for #{name}:\n#{journalctl_output}"
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Check the journalctl excerpt in the message and `systemctl status <name>` to see whether the process ignored the term signal or timed out.
  2. Raise `TimeoutStopSec` in the unit file (or set a larger Puppet `timeout` on the resource) so slow shutdowns can complete.
  3. Fix the unit's `KillMode`/`KillSignal` so systemd can actually terminate the process (default KillMode=control-group is usually correct).
  4. Manually verify with `systemctl stop <name>` on the node; use `systemctl kill <name>` to force if the process is stuck.
  5. Ensure the daemon's PID file / Type=forking settings match reality so systemd tracks the right main PID.

Example fix

# before
service { 'myapp': ensure => stopped }
# after - allow more time for graceful shutdown
service { 'myapp':
  ensure  => stopped,
  timeout => 300,
}
Defensive patterns

Strategy: retry

Validate before calling

systemctl is-active myapp  # confirm current state before ensure => stopped sync
sc_out = Puppet::Util::Execution.execute(['systemctl', 'show', 'myapp', '-p', 'TimeoutStopUSec'], failonfail: false)

Try / catch

attempts = 0
begin
  attempts += 1
  provider.stop
rescue Puppet::Error => e
  raise unless e.message.start_with?('Systemd stop for') && attempts < 3
  Puppet.info "stop timed out, forcing (attempt #{attempts})"
  Puppet::Util::Execution.execute(['systemctl', 'kill', 'myapp'])
  retry
end

Prevention

When it happens

Trigger: `ensure => stopped` sync or explicit stop where `systemctl stop <name>` times out or errors: main process ignores SIGTERM and TimeoutStopSec expires, KillMode=none leaves children behind, the unit is in a D-state process, or systemd's DBus connection is broken.

Common situations: Legacy daemons that do not handle SIGTERM; containers with KillMode misconfigured; a hung process blocking shutdown; stop attempted while systemd itself is degenerate (e.g., after OOM events).

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/bf459aceae265376. Report an issue: GitHub.