Fix Suspend, Resume and Hibernate Problems on Linux
Find out which sleep mode you use and read the log of the last failed attempt. That tells you which of the fixes below applies:
cat /sys/power/mem_sleep
journalctl -b -1 -e
journalctl -b -u systemd-suspend.service
On NVIDIA systems that resume to a black screen, enable the driver's sleep services:
sudo systemctl enable nvidia-suspend.service nvidia-resume.service nvidia-hibernate.service
Identify your case
| Symptom | Most likely cause |
|---|---|
| Screen turns off, then the system wakes again within seconds | A wakeup source (USB, network, Bluetooth, lid sensor) |
| Suspends fine, resume shows a black screen or frozen desktop | GPU driver (often NVIDIA), or a display/compositor crash |
| Fans keep running, battery drains overnight | s2idle not reaching low-power states |
| Nothing happens when you choose Suspend or close the lid | An inhibitor lock, logind lid settings, or suspend disabled |
| Hibernate is missing or fails | No swap, swap too small, no resume setting, or Secure Boot lockdown |
| System reboots instead of resuming | Firmware/ACPI bug, or a hibernation image the kernel cannot find |
Diagnose step by step
Step 1: Check the sleep modes
cat /sys/power/state
cat /sys/power/mem_sleep
Example output:
freeze mem disk
[s2idle] deep
The value in brackets is active. If only [s2idle] is listed, the firmware supports nothing else and switching to S3 is not possible. If deep is offered and s2idle misbehaves (battery drain, failed wake), test deep sleep for one session:
echo deep | sudo tee /sys/power/mem_sleep
systemctl suspend
If that works better, make it permanent with the mem_sleep_default=deep kernel parameter. Some firmware also has a BIOS option such as Sleep State: Linux or S3 that makes deep available.
Step 2: Read the logs from the failed attempt
If the machine had to be powered off, the evidence is in the previous boot's journal:
journalctl -b -1 -e
journalctl -b -1 | grep -iE 'suspend|resume|PM:|nvidia|amdgpu|i915|error'
Look for the last line before the log stops. PM: suspend entry followed by nothing means the system never came back; a driver name in an error just before that line is the suspect. If logs from the previous boot are missing, enable persistent journaling with sudo mkdir -p /var/log/journal and reproduce the problem.
Step 3: Check inhibitors and lid settings
systemd-inhibit --list
grep -E '^(HandleLid|HandleSuspend)' /etc/systemd/logind.conf /etc/systemd/logind.conf.d/*.conf 2>/dev/null
An app holding a sleep lock with mode block (a download manager, a video call, some IDEs) prevents suspend. If closing the lid does nothing, set the lid action in a drop-in file, which survives package updates:
sudo mkdir -p /etc/systemd/logind.conf.d
printf '[Login]\nHandleLidSwitch=suspend\nHandleLidSwitchExternalPower=suspend\n' | sudo tee /etc/systemd/logind.conf.d/lid.conf
sudo systemctl restart systemd-logind
Restarting systemd-logind can end your graphical session. Save your work first, or simply reboot instead.
Step 4: Test the suspend stages
If the machine hangs on the way down or never comes back, the kernel's pm_test mode lets you run suspend up to a certain stage and return automatically after five seconds. It works on kernels built with PM debugging, which includes Ubuntu's and Fedora's:
cat /sys/power/pm_test
echo devices | sudo tee /sys/power/pm_test
echo mem | sudo tee /sys/power/state
echo none | sudo tee /sys/power/pm_test
Try freezer, then devices, then platform. The first stage that hangs points to the culprit: freezer means a process cannot be frozen, devices means a driver fails to suspend, platform points to the firmware. Always set pm_test back to none afterwards, or real suspends will keep returning after five seconds.
Once you suspect a driver, unloading it before suspend is a good test. For example, some Wi-Fi and touchpad drivers misbehave; a script in /usr/lib/systemd/system-sleep/ can unload and reload a module around suspend:
#!/bin/sh
# /usr/lib/systemd/system-sleep/unload-wifi (make it executable)
case "$1" in
pre) modprobe -r mt7921e ;;
post) modprobe mt7921e ;;
esac
Replace mt7921e with the module you identified (lspci -k shows it).
Fix: the system wakes up immediately
List the ACPI devices allowed to wake the machine:
cat /proc/acpi/wakeup
Example output:
Device S-state Status Sysfs node
GPP0 S4 *enabled pci:0000:00:01.1
XHC0 S4 *enabled pci:0000:05:00.3
LID S4 *enabled platform:PNP0C0D:00
Toggle one entry at a time (writing the name flips its state) and test suspend after each:
echo XHC0 | sudo tee /proc/acpi/wakeup
systemctl suspend
Common culprits are USB controllers (XHC, XHCI) with a wireless mouse dongle, and PCIe ports (GPP, RP) hosting a network card. For a single USB device, use its own wakeup flag instead of disabling the whole controller:
grep . /sys/bus/usb/devices/*/power/wakeup
echo disabled | sudo tee /sys/bus/usb/devices/1-3/power/wakeup
These changes reset at boot. Make them permanent with a udev rule or a small systemd service once you know which device is responsible. Wired network cards with Wake-on-LAN enabled can be checked with sudo ethtool <interface> | grep Wake-on.
Fix: black screen after resume (NVIDIA and other GPUs)
The NVIDIA driver must save video memory before sleeping. Check that it is configured to do so and that its helper services are on:
grep PreserveVideoMemory /proc/driver/nvidia/params
systemctl is-enabled nvidia-suspend.service nvidia-resume.service nvidia-hibernate.service
If the parameter is 0, enable it with a modprobe option, then regenerate the initramfs and reboot:
echo 'options nvidia NVreg_PreserveVideoMemoryAllocations=1 NVreg_TemporaryFilePath=/var/tmp' | sudo tee /etc/modprobe.d/nvidia-power.conf
sudo systemctl enable nvidia-suspend.service nvidia-resume.service nvidia-hibernate.service
# regenerate the initramfs (commands in the hibernation section below), then reboot
The temporary file path must be on a disk filesystem with free space at least as large as your video memory; /tmp on tmpfs is too small on many systems. If the driver is broken entirely rather than just failing on resume, use the NVIDIA black screen guide.
For Intel and AMD, a black screen after resume is usually a kernel driver regression. Try switching to a text console with Ctrl+Alt+F3: if that works, the kernel is alive and the desktop crashed; log in again or restart the display manager. If the machine is completely frozen, boot an older kernel to compare.
Fix: battery drain during s2idle
s2idle only saves power if every device reaches a low-power state. Check how long the system actually spent in the deepest state (Intel):
sudo cat /sys/kernel/debug/pmc_core/slp_s0_residency_usec
If the number does not increase after a suspend, something blocked low-power idle. Typical causes are an NVMe drive without power management, a discrete GPU that stays on, or out-of-date firmware. Update firmware with fwupdmgr update and keep the kernel current; s2idle behaviour improves with almost every kernel release. AMD systems can be diagnosed with the amd_s2idle.py script from the AMD kernel developers.
Fix: hibernation
Hibernation writes RAM to swap and powers off. It needs four things:
- Enough swap. At least the amount of RAM in use, safest equal to total RAM. A
zramdevice does not count, because it lives in RAM. Check withswapon --show. - A resume target. On UEFI systems with a recent systemd, the resume location is passed automatically through an EFI variable. Otherwise add
resume=UUID=<swap-uuid>(fromblkid), plusresume_offset=for a swap file:# ext4 swap file sudo filefrag -v /swapfile | awk 'NR==4{print $4}' # Btrfs swap file sudo btrfs inspect-internal map-swapfile -r /swapfile - Resume support in the initramfs. Arch with the busybox-based mkinitcpio needs the
resumehook (thesystemdhook handles it automatically). Regenerate:sudo mkinitcpio -P(Arch),sudo dracut -f(Fedora, openSUSE, Ubuntu 26.04),sudo update-initramfs -u(Debian, Ubuntu 24.04). - No kernel lockdown. With Secure Boot enabled, distro kernels enter lockdown mode, which disables hibernation.
cat /sys/kernel/security/lockdownshows the mode; see Secure Boot on Linux for the trade-offs.
Test with systemctl hibernate. Once it works, suspend-then-hibernate (configured in /etc/systemd/sleep.conf.d/ with HibernateDelaySec=) gives you fast wake for short breaks and no battery drain overnight.
Distro notes
- Ubuntu 26.04 / 24.04: the NVIDIA packages from
ubuntu-driversenable the suspend services. Hibernate is not shown in GNOME's menu even when it works; usesystemctl hibernate. - Fedora 44: uses zram swap by default, so hibernation needs an additional disk swap partition or Btrfs swap file. The RPM Fusion NVIDIA packages ship the suspend services.
- Arch Linux:
nvidia-utilsships the services; enable them yourself. Add theresumehook if you hibernate. - Linux Mint: configure lid and power behaviour in Power Management settings, which override logind.
- openSUSE: Leap 16 and Tumbleweed also put Secure Boot kernels into lockdown; the same hibernation restriction applies.
Last resort
- Test with an older and a newer kernel. Suspend regressions are often fixed or introduced by a single release.
- Disconnect all USB devices and docks, then test. Docks are a frequent cause of failed resume.
- Update the BIOS/UEFI; many vendors ship Linux-relevant sleep fixes only as firmware.
- If nothing helps, disable the broken state and use the other one, or hibernate instead of suspend, until a fix lands. Report the bug with the journal output from Step 2.
Frequently asked questions
What is the difference between s2idle and deep sleep?
s2idle (suspend-to-idle, Modern Standby) freezes software and lets the CPU idle while the hardware stays powered, so it wakes fast but can drain more battery. deep (S3) powers down almost everything except RAM. Many laptops from 2020 onward only offer s2idle.
Why does my laptop wake up immediately after suspend?
A wakeup source such as a USB device, the Wi-Fi card, Bluetooth or a network card with Wake-on-LAN triggers right away. Check journalctl -b -u systemd-suspend and /proc/acpi/wakeup, then disable the offending source.
Why is hibernate missing or disabled on Ubuntu?
Ubuntu does not enable hibernation by default: it needs swap at least as large as your RAM contents, a resume setting, and it is blocked when Secure Boot puts the kernel into lockdown mode. Suspend works without any of these.
How do I fix a black screen after resume with NVIDIA?
Make sure nvidia-suspend, nvidia-resume and nvidia-hibernate services are enabled and that the driver preserves video memory (NVreg_PreserveVideoMemoryAllocations=1). Distro NVIDIA packages usually set this up; manual installs often do not.
Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.