Read the log before you believe your own story
I was sure one of my machines was restarting itself around eight in the morning, a couple of times a week, while nobody was using it. I had said it out loud more than once. I had a theory about why. I went to the event log to confirm it, which felt like a formality.
In forty five days, that machine had booted at eight o'clock exactly once.
The cluster was not at eight at all. It was at ten and eleven. My story was not slightly off, it was wrong, and I had been reasoning from it for weeks. Every plan I had sketched to catch the eight o'clock reboot would have sat there watching an hour when nothing ever happened.
Your memory of your own system is a story. The log is evidence. Stories are built from the times you happened to notice, which means they are built from a biased sample of your own attention. You remember the morning you walked in and found it freshly booted. You do not remember the ten mornings it was fine.
But the log did not hand me one clean answer either, and this is the part worth staying for. There were two different causes wearing the same costume, and either one on its own would have looked like "it reboots sometimes".
The first was real crashes. Six of them across three weeks, all with an identical signature, all pointing at the graphics driver. The machine was configured to restart itself immediately after a crash, which is a sensible default and also the reason nobody ever saw a crash. It would fall over and be back before anyone looked, leaving no impression except a machine that was mysteriously freshly booted. That behaviour, restart on failure, is exactly what made the failure invisible.
The second was the operating system installing updates. That one was not a fault at all. It was the machine doing precisely what it had been configured to do, on a schedule I had set and forgotten. Updates were told to avoid a protected window covering the hours I was likely to be working, so they waited politely all night and then fired the moment that window ended in the morning. Not random. Not broken. A monthly appointment I had made myself.
Two causes, one symptom, and averaging them together produced the fiction of a twice weekly eight o'clock reboot that existed nowhere but in my head. If you find yourself explaining an intermittent problem with a single tidy cause, consider that you may be looking at two problems taking turns.
The fix for the annoying half was small. There is a setting that tells the system to keep downloading and installing updates as normal but to stop restarting on its own, and wait for a human instead. Updates keep flowing, which matters, because the popular alternative is switching updates off and that trades a small annoyance for a real security problem.
And here is the catch I will not paper over. That setting is an older one, from a previous generation of the update system, and the reboots I actually caught in the log were being driven by the newer machinery. The value is set. Whether it will hold is not proven, and I cannot prove it today. The real test is the next update cycle, and I know the date it will happen. If the machine restarts itself that morning anyway, the setting did not take and the next lever is the schedule window itself.
I would rather tell you that now than have you read this, apply it, and get surprised in a month. A fix you have not yet seen survive a real cycle is a hypothesis with good paperwork.
The lesson: go and read the evidence before you act on the story, including and especially when the story is yours. Then check whether the pattern you found is one thing or two things standing very close together.
How to get the actual restart history out of a machine, tell a crash apart from a scheduled reboot, find the window that decides when reboots land, and keep your updates without the surprise. Read only until the last step.
1. Pull the real boot history
Start with the raw list of boots and the hour each one happened. Do not summarise it in your head, put it in a column and count. This is the step that either confirms your story or ends it.
# Linux: every boot the journal remembers
journalctl --list-boots
# count them by hour, which is what actually answers the question
journalctl --list-boots -o short-iso \
| awk '{print $4}' | cut -d: -f1 | sort | uniq -c | sort -rn
# Windows: 6005 boot, 6006 clean shutdown, 6008 unexpected, 1074 who asked
Get-WinEvent -FilterHashtable @{LogName='System'; Id=6005} |
Group-Object { $_.TimeCreated.Hour } | Sort-Object Name |
Format-Table Name, Count
2. Separate the crashes from the planned restarts
These are different problems with different fixes, so split them before you theorise. A planned restart names the process that requested it. A crash does not, because nothing requested it.
# Linux: did it shut down cleanly, or just stop?
journalctl -b -1 -p err --no-pager | tail -20
last -x reboot shutdown | head
# Windows: 1074 tells you WHICH process asked, and why
Get-WinEvent -FilterHashtable @{LogName='System'; Id=1074} |
Select-Object TimeCreated, Message -First 10
3. Read the crash code, it usually names the culprit
Crashes are not anonymous. On Windows the bugcheck record carries a code and parameters, and one of those parameters is very often a hardware vendor identifier that points straight at a driver. Mine were identical across all six, which is itself information: identical crashes mean one cause, not bad luck.
Get-WinEvent -FilterHashtable @{LogName='System'; Id=1001} |
Select-Object TimeCreated, Message -First 10
# then look up the bugcheck code. the parameters matter as much as the code.
# Linux equivalent: the last words of the previous boot
journalctl -b -1 -k --no-pager | tail -40
4. Find the window that decides when reboots are allowed
If restarts cluster at one particular hour, something is almost certainly holding them until that hour. Find the protected window and the clustering usually explains itself instantly.
# Windows: the hours updates are told NOT to restart in
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings' |
Select-Object ActiveHoursStart, ActiveHoursEnd
# Linux: the timer that runs unattended upgrades, and when it last fired
systemctl list-timers --all | grep -i -E 'upgrade|update'
grep -r 'Automatic-Reboot' /etc/apt/apt.conf.d/ 2>/dev/null
Reboots landing right after a protected window closes is not a coincidence, it is the window working exactly as designed.
5. Keep the updates, remove the surprise
The goal is not to stop updating. It is to stop the machine deciding on its own when to drop what you were doing. Both systems can install on their own schedule and still wait for you to say when to restart.
# Windows: install as normal, but do not auto-restart while signed in
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" ^
/v NoAutoRebootWithLoggedOnUsers /t REG_DWORD /d 1 /f
gpupdate /force
# Linux: install security updates, never reboot by itself
# /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Automatic-Reboot "false";
Back up whatever you are about to change first, and write down how to undo it. On Windows, export the key before you touch it; if it does not exist yet, that absence is your backup and the rollback is simply deleting what you added.
6. Verify it held, and know when you will find out
Read the value back rather than trusting that the command worked. Then put a note in your calendar for the next update cycle, because that is the only thing that actually proves it, and be honest with yourself that until that date passes you have a hypothesis rather than a fix.
reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" \
/v NoAutoRebootWithLoggedOnUsers
# and confirm updates are still flowing, which is the point
Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 5
One honest trade to accept: with automatic restarts off, updates will queue up until you restart the machine yourself. Put a recurring reminder in for that, otherwise you have swapped a surprise reboot for a pile of unapplied security patches, which is the worse of the two.
Related: prove the monitor is not the thing that is broken is the same instinct pointed at your alerting, and measure before you delete is the same instinct pointed at your disk.