I am running a Rpi 3b+ headless, mostly for Pi-Hole now. Nothing external connected, not even a monitor, a mouse or a keyboard.

But because it runs PiHole, and my DHCP clients use it as domain server, it's crucial in my setup.

But it keeps shutting down randomly.

Its power supply is 5V 2500mA. This shouldn't be the issue.

I can only think of my shutdown button script. It is registered as init.d script, and listens to GPIO

#!/usr/bin/env python

import RPi.GPIO as GPIO
import subprocess

GPIO.setup(3, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.wait_for_edge(3, GPIO.FALLING)

subprocess.call(['/usr/local/bin/cleanup.sh'], shell=True)
subprocess.call(['shutdown', '-h', 'now'], shell=False)

Don't remember where I got this from (for due credits). Could possibly the GPIO.FALLING occur for different reasons other than me pushing the connected button? Is there maybe some safer way for me to do this?

EDIT: Just found this log also:

Mar 23 11:33:10 raspberrypi listen-for-shutdown.sh[514]: /usr/local/bin/listen-for-shutdown.py:8: RuntimeWarning: A physical pull up resistor is fitted on this channel!
Mar 23 11:33:10 raspberrypi listen-for-shutdown.sh[514]:   GPIO.setup(3, GPIO.IN, pull_up_down=GPIO.PUD_UP)

Or any other ideas? Looking at the syslog, there's nothing to see other than logs of this script before shutting down. You can see I call a cleanup.sh script here, and there's a log of it out of the blue before shutting down, so this means to me this GPIO stuff triggers the shutdown:


echo "Running cleanup script..."
#does some other cleanup before shutdown

The logs show firewall stuff and out of the blue the cleanup script log:

Mar 23 11:32:02 raspberrypi kernel: [222378.037634] [UFW BLOCK] IN=eth0 OUT= MAC=<MAC> SRC= DST= LEN=357 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1900 DPT=48807 LEN=337 
Mar 23 11:32:02 raspberrypi kernel: [222378.141760] [UFW BLOCK] IN=eth0 OUT= MAC=<MAC> SRC= DST= LEN=351 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1900 DPT=48807 LEN=331 
Mar 23 11:32:47 raspberrypi listen-for-shutdown.sh[463]: Running cleanup script...
Mar 23 11:32:50 raspberrypi systemd[1]: Stopped target Timers.
Mar 23 11:32:50 raspberrypi systemd[1]: systemd-tmpfiles-clean.timer: Succeeded.

The listen-for-shutdown.sh is at /etc/init.d/listen-for-shutdown.sh, and triggers the above python script:

case "$1" in
    echo "Starting listen-for-shutdown.py"
    /usr/local/bin/listen-for-shutdown.py &
    echo "Stopping listen-for-shutdown.py"
    pkill -f /usr/local/bin/listen-for-shutdown.py
    echo "Usage: /etc/init.d/listen-for-shutdown.sh {start|stop}"
    exit 1

exit 0
  • Why would you want to run a process to implement a shutdown button when there is a perfectly good Device Tree overlay to do this?
    – Milliways
    Mar 26 at 21:23
  • Huh, no idea what you are talking about. Going to google Device Tree Mar 26 at 21:37
  • 1
    Just search this forum. I have written answers about this, dtoverlay shutdown from memory I am currently unable to access them but could post a link later.
    – Milliways
    Mar 26 at 21:41
  • This looks to be one: raspberrypi.stackexchange.com/a/77918/77317 Mar 26 at 21:46
  • I think there are more recent posts but the process remains the same. I implemented this on all my Pi (except Pi5) and even without a button can shut down by using a shunt on pin 39,40
    – Milliways
    Mar 26 at 22:15

2 Answers 2


I'll suggest a simplification that may solve your problem:

You do not need this software. The One Button ON-OFF setup has been around for years. It requires two pieces of wire, and one momentary push-button switch.

IOW: no software beyond a single line calling out the dtoverlay in the "config file":


Where is the "config file" you may be wondering... That depends on which version of the OS you're using (should have stated that in your question BTW):

For bullseye & prior:

The "config file" is located at: /boot/config.txt

For bookworm:

The "config file" is located at: /boot/firmware/config.txt

And the really great thing about the gpio-shutdown overlay is that it even has the switch debounce logic built in.

  • This looks promising, I'll try this out! Mar 27 at 15:50
  • @unsafe_where_true: I hope this helped?
    – Seamus
    Apr 10 at 16:04

so this means to me this GPIO stuff triggers the shutdown

You don't have to guess. Just put a line in the python script to log something including the exact time to a file (or syslog), and that should cinch the deal (which sounds pretty cinched as is).

WRT the problem, you should put some debounce in there to prevent spurious triggers. Experiment with that first using a button that does nothing, it may require some fine tuning.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.