dmesg Kernel Log Analysis: Finding Errors in the Ring Buffer
AI generated
$
/etc
Linux · Kernel · System Internals · Administration
dmesg Kernel Log Analysis
Finding ring buffer errors before they become an outage

The kernel writes every important message, from hardware detection at boot to the OOM killer during live operation, into an internal ring buffer that dmesg makes readable. Anyone who masters kernel log analysis with dmesg finds driver failures, memory problems and hardware defects often minutes before they show up as an application outage, instead of searching for the cause only afterward.

17 min read dmesg · journalctl -k · kernel ring buffer · log levels Ubuntu · Debian · RHEL · Kernel 5.x/6.x

1. What the kernel ring buffer is and how dmesg reads it

The dmesg command reads the kernel ring buffer, a fixed-size data structure permanently reserved in kernel memory that the kernel writes every important message into since boot. The name dmesg stands for display message, and because it is a ring buffer, new messages overwrite the oldest ones once the reserved memory is full. That is exactly the central practical point of any kernel log analysis: on a system with very active kernel logging, for example from frequent hardware events, important older messages may already be overwritten before an administrator ever reads them.

Without arguments, dmesg shows the entire current buffer content since the last boot. The buffer size is set at kernel startup via the boot parameter log_buf_len and is usually between 256 KB and several megabytes on modern systems, considerably more than in the past, but still finite. For effective kernel log analysis, raw dmesg rarely suffices, because the buffer quickly becomes overwhelming. Combining time filtering, log level filtering and targeted grep turns the raw data stream into a usable diagnostic source.


# Show the entire current ring buffer content since last boot
dmesg

# Show buffer size configured at boot (kernel parameter log_buf_len)
cat /proc/cmdline | grep -o 'log_buf_len=[^ ]*'

# Human-readable timestamps instead of raw boot-relative seconds
dmesg -T

# Colorize output by severity, easier to scan visually
dmesg -x --color=always | less -R

2. Interpreting timestamps and ordering correctly

By default, dmesg shows timestamps as seconds since system startup, in square brackets, for example [ 3.482911]. This boot-relative time is useful for kernel log analysis right after a reboot, but becomes unwieldy quickly on a system with high uptime, since you would need to calculate yourself which calendar date [ 892341.223] corresponds to. The -T option converts these timestamps to human readable calendar time, based on the current system time and the difference from boot time.

An important caveat many miss during kernel log analysis: the -T conversion is an approximation, because it does not account for NTP time corrections between boot and the current moment. On systems whose clock deviated significantly at boot and was only synced later via NTP, the converted timestamps can be off by several minutes from the actual event time. For forensic accuracy, for example during a security investigation, journalctl -k is preferable, because systemd-journald tags every entry with its own correctly synced timestamp instead of computing it retroactively.


# Raw boot-relative timestamp in seconds
dmesg | head -3
# [    0.000000] Linux version 6.8.0-generic ...
# [    0.004123] Command line: BOOT_IMAGE=...

# Human-readable calendar time (approximate, not NTP-corrected)
dmesg -T | head -3
# [Thu Jul 30 08:12:03 2026] Linux version 6.8.0-generic ...

# For forensic accuracy, prefer journalctl, which stores real timestamps
journalctl -k --since "1 hour ago" -o short-precise

# Find how long the system has been up (context for interpreting timestamps)
uptime -s

3. Filtering log levels: from emergency to debug

Every kernel message carries a severity level, the same scale as syslog: 0 for emerg (system unusable), 1 for alert, 2 for crit, 3 for err, 4 for warn, 5 for notice, 6 for info, and 7 for debug. In the default dmesg output this level is not directly visible, but the -l option filters by severity, which is essential for focused kernel log analysis. On a production system with thousands of lines in the buffer, dmesg -l err,crit,alert,emerg is often the fastest way to jump straight to relevant problems without wading through informative but irrelevant messages.

The -x option additionally shows the facility, the kernel subsystem category of a message, which helps distinguish real hardware failures from harmless informational messages. A common beginner mistake in kernel log analysis: messages at warn level get ignored across the board, even though some warnings, such as repeated ECC memory corrections, are early signs of hardware about to fail. Good practice is to review warn and higher levels regularly, not just restrict yourself to err and worse.


# Filter by severity level, skipping informational noise
dmesg -l err,crit,alert,emerg

# Show facility (subsystem) alongside severity
dmesg -x | tail -30

# Common facilities: kern, daemon, user; common levels: err, warn, info
dmesg -l warn,err,crit -x

# Count messages by severity to spot an unusually noisy subsystem
dmesg -x | awk -F: '{print $1}' | sort | uniq -c | sort -rn

4. Spotting hardware and driver failures in dmesg

The classic use case for dmesg is diagnosing hardware problems, because the kernel immediately logs every detected error from a device driver. A failing or overheating storage device typically shows up as repeated I/O error or ATA error messages naming the affected device such as sda or nvme0n1. Network card problems often appear as link down followed by link up in rapid succession, a pattern pointing to an unstable cable or a faulty switch port rather than a software problem.

For kernel log analysis when hardware is suspected, combining grep for the affected device with looking at the time context is decisive: a single I/O error can be a transient event, while a series with rising frequency over hours or days points to progressive hardware wear. SMART data via smartctl complements dmesg by providing proactive self test results, while dmesg reactively shows what the kernel has already registered as an error.


# Disk I/O errors, filtered by device name
dmesg -T | grep -iE "sda|nvme0n1" | grep -iE "error|fail"

# Network link flapping pattern (unstable cable or switch port)
dmesg -T | grep -iE "link (is )?(up|down)"

# USB device connect/disconnect events, useful for intermittent hardware
dmesg -T | grep -i usb | tail -20

# Generic hardware error scan across the whole buffer
dmesg -T -l err,crit,alert,emerg | grep -iE "error|fault|fail|timeout"

# Cross-check with SMART for proactive disk health, complementary to dmesg
sudo smartctl -a /dev/sda | grep -i "reallocated\|pending"

5. Reading and understanding OOM killer messages

When the system runs out of available memory, the kernel's out-of-memory killer steps in and deliberately terminates a process to save the system from a complete crash. This decision is logged in detail in the kernel ring buffer, and kernel log analysis of these messages is often the only way to find out why a process suddenly disappeared with no discernible error of its own. The message Out of memory: Killed process 1234 (php-fpm) names both the PID and process name of the terminated process.

Before this final line, the kernel logs a detailed table of every process with its oom_score, the internal value the OOM killer uses to decide which process to sacrifice. A high oom_score means a higher risk of being selected, influenced by memory usage and the adjustable value oom_score_adj. This table in dmesg shows exactly which processes were using how much memory at the moment of the event, and is often more informative than after-the-fact monitoring, which can no longer reconstruct the state before the crash.


# Find every OOM-killer event in the current buffer
dmesg -T | grep -i "out of memory"

# The line that names the actual killed process
dmesg -T | grep -i "killed process"
# [Thu Jul 30 03:14:02 2026] Out of memory: Killed process 1234 (php-fpm)
#   total-vm:892340kB, anon-rss:412332kB, file-rss:0kB

# Full context: the process table dmesg prints right before the kill
dmesg -T | grep -B 40 "Killed process" | grep -E "oom_score_adj|pid|php-fpm"

# Persistent OOM history across reboots via journalctl
journalctl -k --since "7 days ago" | grep -i "out of memory"

6. Network and filesystem warnings in the ring buffer

Filesystem errors are among the most critical messages a kernel log analysis can surface, because they often indicate data corruption. Messages such as EXT4-fs error or XFS: Internal error show that the kernel found an inconsistency in the filesystem structure, usually caused by an unclean shutdown, a hardware fault on the underlying storage device, or in rare cases a kernel bug. Such messages should never be ignored, because some filesystems automatically switch to read-only mode after such an error to prevent further damage.

On the network side, the kernel logs among other things TCP retransmission problems, ARP conflicts from duplicate IP addresses on the local network, and firewall drops, provided iptables or nftables are configured with a LOG target. These logged firewall drops also appear in the kernel ring buffer, because they are generated by the netfilter subsystem inside the kernel itself, not by a userspace daemon. For kernel log analysis in a network context, dmesg is therefore a full-fledged complement to classic network tools such as tcpdump, especially for events decided at kernel level.


# Filesystem corruption warnings (never ignore these)
dmesg -T | grep -iE "ext4-fs error|xfs.*internal error|i/o error"

# Duplicate IP address detected via ARP conflict
dmesg -T | grep -i "duplicate address"

# Firewall drops logged via iptables/nftables LOG target (kernel-level)
dmesg -T | grep -i "IN=.*OUT=.*"

# TCP-level retransmission or connection reset noise
dmesg -T | grep -iE "tcp.*retransmit|connection reset"

7. Persistent logging: dmesg limitations and journalctl -k

A central drawback of plain dmesg: it only shows the buffer of the current boot, unless the system uses a persistent kernel log directory. After a reboot, the entire history of the previous boot is lost, which makes retroactive kernel log analysis after a crash impossible unless precautions were taken. Systemd-based distributions solve this with journalctl -k, which reads the same kernel messages but stores them persistently on disk if Storage=persistent is set in /etc/systemd/journald.conf.

The decisive advantage of journalctl -k over plain dmesg: boot history is preserved and accessible via journalctl -k -b -1 for the second-to-last boot, which is especially valuable after an unexpected reboot to find the last message before the failure. Without persistent journal logging, all that remains is hoping an external log collector already forwarded the dmesg output before the crash, which is not the case in many default setups.


# Enable persistent journal storage (survives reboots)
sudo mkdir -p /etc/systemd/journald.conf.d
cat <<'EOF' | sudo tee /etc/systemd/journald.conf.d/persistent.conf
[Journal]
Storage=persistent
SystemMaxUse=500M
EOF
sudo systemctl restart systemd-journald

# Kernel messages from the current boot
journalctl -k -b 0

# Kernel messages from the previous boot (crash investigation)
journalctl -k -b -1

# List all available boots with their approximate time range
journalctl --list-boots

8. Integrating dmesg into monitoring and automation

For production systems, it pays off to automate kernel log analysis continuously instead of only reactively during a problem. A simple cron script that regularly searches for critical log levels and alerts on new hits catches many hardware problems early, before they escalate into an outage. Important here: the script's state must be persisted, for example the last seen timestamp, so the same message does not trigger an alert again on every run.

For lasting integration into existing monitoring stacks, journalctl -k -f as a follow mode outputs new kernel messages in real time and can be fed into a log shipping tool such as Filebeat or Fluentd. Kernel log analysis then becomes part of central logging instead of an isolated, manual task performed only after an incident has already occurred.


#!/usr/bin/env bash
# Simple cron-driven check for new critical kernel messages
set -euo pipefail

STATE_FILE="/var/lib/dmesg-monitor/last-check.timestamp"
mkdir -p "$(dirname "$STATE_FILE")"

LAST_CHECK=$(cat "$STATE_FILE" 2>/dev/null || echo "1970-01-01 00:00:00")
NOW=$(date '+%Y-%m-%d %H:%M:%S')

NEW_CRITICAL=$(journalctl -k --since "$LAST_CHECK" -p err..emerg -o cat)

if [[ -n "$NEW_CRITICAL" ]]; then
  echo "[ALERT] New critical kernel messages since $LAST_CHECK:"
  echo "$NEW_CRITICAL"
  # Send to alerting system, e.g. curl to a webhook
fi

echo "$NOW" > "$STATE_FILE"

# Real-time follow mode, suitable for feeding a log shipper
# journalctl -k -f -o json | your-log-shipper --stdin

9. dmesg compared to other log sources

dmesg is one of several log sources on Linux, and proper kernel log analysis requires knowing which source is responsible for which type of message.

Source Content Persistent Typical use
dmesg Kernel ring buffer, current boot no, current boot only Quick live diagnosis
journalctl -k Same kernel messages yes, with Storage=persistent Historical analysis across boots
/var/log/syslog Kernel and userspace messages mixed yes, with logrotate Classic text logging on non-systemd systems
Application logs Application level only, no kernel yes Business logic errors, not kernel events

In practice these sources complement each other: dmesg for a quick live check directly on the server, journalctl -k for analysis after a failure including the previous boot, and application logs for everything happening above the kernel level. A complete kernel log analysis always considers which level a problem affects, instead of relying on a single log source.

Mironsoft

Linux troubleshooting, kernel log analysis and server monitoring

Server crashes nobody can explain the cause of?

We set up persistent kernel logging, automate kernel log analysis, and find the real cause behind OOM kills, hardware failures and filesystem warnings.

Log persistence

Configuring journalctl storage so no boot incident is ever lost

Automated alerting

Automatically detecting and reporting critical kernel messages

Root cause analysis

Systematically clarifying OOM kills, hardware faults and filesystem warnings

10. Summary

Kernel log analysis with dmesg is one of the most direct ways to understand what actually happens at kernel level, from hardware detection at boot to OOM kills during live operation. The kernel ring buffer that dmesg makes readable has a finite size and loses its content on reboot, which is why persistent logging via journalctl -k is indispensable for production systems. Log level filtering with dmesg -l and timestamp conversion with -T turn the raw buffer into a specifically searchable diagnostic source.

Anyone who integrates kernel log analysis into monitoring scripts, instead of only running it reactively after a failure, discovers hardware problems, memory pressure and filesystem warnings often before they lead to a complete outage. The combination of dmesg for quick live checks and journalctl -k for historical analysis across boots covers the complete practical need.

dmesg kernel log analysis — the key points at a glance

Understanding the ring buffer

Finite size, older messages get overwritten, only valid for the current boot.

Filtering by level

dmesg -l err,crit,alert,emerg jumps straight to relevant problems without informational noise.

OOM and hardware

OOM kills, filesystem errors and link flapping are all directly visible in the ring buffer.

Persistence

journalctl -k with Storage=persistent keeps history across reboots.

11. FAQ: dmesg Kernel Log Analysis

1What does dmesg mean?
Display message, shows the kernel ring buffer with all important messages since boot.
2Why are older messages missing?
The ring buffer has limited size, new messages overwrite the oldest ones.
3Is dmesg -T always exact?
No, without NTP correction between boot and today the conversion can be inaccurate.
4Filtering for critical messages?
dmesg -l err,crit,alert,emerg shows only relevant severities without noise.
5Recognizing an OOM kill?
The line Killed process with PID and name, preceded by a process table with oom_score.
6No old messages after reboot?
Without persistent journal, the history of a previous boot is completely lost.
7Enabling persistent logging?
Set Storage=persistent in journald.conf and restart systemd-journald.
8Firewall drops visible in dmesg?
Yes, with a LOG target in iptables/nftables messages appear directly in the ring buffer.
9Automating kernel log analysis?
Cron script with journalctl -k --since and a stored last check timestamp, or journalctl -k -f for real time.
10dmesg vs. journalctl -k?
Both show the same messages, journalctl -k can also show earlier boots with persistent storage enabled.