FreeBSD.software
Home/Guides/FreeBSD Troubleshooting: Common Problems and Solutions (2026)
guide·2026-04-09·16 min read

FreeBSD Troubleshooting: Common Problems and Solutions (2026)

Solve the most common FreeBSD problems: boot failures, network issues, package conflicts, disk errors, performance problems, kernel panics, ZFS pool issues, and service failures. Diagnostic commands and fixes for each.

FreeBSD Troubleshooting: Common Problems and Solutions (2026)

Every FreeBSD system will eventually hit a wall -- a boot that hangs, a network interface that vanishes, a ZFS pool that goes degraded at 3 AM. This guide is a field manual for those moments. Each section gives you the diagnostic command first, then the fix. No theory, no history lessons -- just the commands you need to get the system back up.

This guide assumes FreeBSD 14.x or later. Most commands require root or sudo access.


1. Boot Failures

Boot failures are the most stressful category because you lose remote access. Knowing the recovery path before you need it is critical.

System Hangs During Boot

Diagnose: Watch the boot output. If it freezes, note the last message. Common culprits are loader.conf misconfigurations, missing kernel modules, or filesystem corruption.

Fix -- Drop to Single-User Mode:

sh
# At the boot loader menu, select option 2 (Single User Mode) # Or press Escape to reach the loader prompt, then: boot -s

Once in single-user mode, you get a root shell with filesystems unmounted. Mount them:

sh
# Mount root read-write mount -u / # Mount all filesystems from fstab mount -a

loader.conf Broke the Boot

If you added a bad line to /boot/loader.conf and the system will not boot:

sh
# At the loader prompt (before the kernel loads), unset the offending variable: unset kern.module_that_breaks_things boot # Once booted, fix the file: vi /boot/loader.conf

If you cannot identify the bad line, bypass loader.conf entirely:

sh
# At the loader prompt: set loader_conf_files="" boot

Filesystem Corruption (fsck)

Diagnose:

sh
# Check filesystem status fsck -n /dev/ada0p2

Fix:

sh
# For UFS filesystems, run fsck in repair mode: fsck -y /dev/ada0p2 # For ZFS, the pool auto-repairs. Force a scrub: zpool scrub zroot zpool status zroot

Boot Environment Recovery

If a system update broke things, roll back using boot environments:

sh
# List available boot environments bectl list # Activate a known-good boot environment bectl activate 2026-03-15_pre-upgrade # Reboot into the working environment reboot

Boot environments are your best safety net during upgrades. See our FreeBSD boot environments guide for full setup instructions.


2. Network Problems

Interface Not Coming Up

Diagnose:

sh
# List all interfaces and their status ifconfig -a # Check if the driver loaded dmesg | grep -i ethernet pciconf -lv | grep -B3 -i network

Fix:

sh
# Bring the interface up manually ifconfig em0 up # Assign an IP if DHCP is not working ifconfig em0 inet 192.168.1.50 netmask 255.255.255.0 # Start DHCP client manually dhclient em0 # Make it persistent in /etc/rc.conf: sysrc ifconfig_em0="DHCP"

DNS Resolution Failures

Diagnose:

sh
# Test raw connectivity (bypass DNS) ping -c 3 8.8.8.8 # Test DNS resolution drill freebsd.org # or host freebsd.org

Fix:

sh
# Check resolver configuration cat /etc/resolv.conf # Set a working nameserver echo "nameserver 1.1.1.1" > /etc/resolv.conf # If using local_unbound (FreeBSD default): service local_unbound restart

Routing Issues

Diagnose:

sh
# Show the routing table netstat -rn # Trace the path to a destination traceroute 8.8.8.8

Fix:

sh
# Set a default gateway manually route add default 192.168.1.1 # Make it persistent sysrc defaultrouter="192.168.1.1"

PF Firewall Blocking Traffic

Diagnose:

sh
# Check if PF is active pfctl -si # Show current ruleset pfctl -sr # Watch blocked packets in real time tcpdump -n -e -ttt -i pflog0

Fix:

sh
# Temporarily disable PF to test if it is the cause pfctl -d # If that fixes it, find and fix the offending rule: pfctl -sr -vv | grep -i block # Reload rules after editing /etc/pf.conf pfctl -f /etc/pf.conf # Re-enable PF pfctl -e

3. Package Issues

FreeBSD's pkg is generally solid, but repository problems, lock conflicts, and broken dependencies happen. See our pkg vs ports comparison for background on the package system.

pkg Lock Conflicts

Diagnose:

sh
# If you see "database is locked" errors: ls -la /var/db/pkg/local.sqlite-journal ps aux | grep pkg

Fix:

sh
# Kill any stale pkg processes pkill -9 pkg # Remove stale lock file rm -f /var/db/pkg/local.sqlite-journal # Rebuild the package database if corrupted pkg update -f

Broken Dependencies

Diagnose:

sh
# Check for missing dependencies pkg check -d -a # Find broken packages pkg check -B -a

Fix:

sh
# Reinstall broken packages pkg install -f <package_name> # Force reinstall all packages with broken dependencies pkg check -d -a -y # Nuclear option: rebuild the entire package database pkg update -f pkg upgrade -f

Repository Errors

Diagnose:

sh
# Test repository connectivity pkg update # Look for HTTP errors, certificate issues, or mirror problems

Fix:

sh
# Switch to a different mirror by editing the repo config: vi /usr/local/etc/pkg/repos/FreeBSD.conf # Use the content: # FreeBSD: { # url: "pkg+http://pkg.FreeBSD.org/${ABI}/quarterly", # enabled: yes # } # Force refresh the repository catalog pkg update -f

Security Audit

Run this regularly:

sh
# Check installed packages for known vulnerabilities pkg audit -F # Update the vulnerability database and audit in one step pkg audit -Fr

4. Disk and ZFS Errors

ZFS is the default filesystem on FreeBSD and it is robust, but hardware failures still happen. Our ZFS on FreeBSD guide covers the fundamentals.

Degraded ZFS Pool

Diagnose:

sh
zpool status # Look for DEGRADED, FAULTED, or UNAVAIL states

Fix -- Replace a Failed Disk:

sh
# Identify the failed disk from zpool status output zpool status zroot # If the disk is still visible but failing: zpool replace zroot /dev/ada1 /dev/ada2 # If the disk is gone and you have a mirror or RAIDZ: zpool replace zroot ada1 ada2 # After replacement, monitor the resilver: zpool status zroot

ZFS Scrub Errors

Diagnose:

sh
# Run a scrub zpool scrub zroot # Check results zpool status -v zroot # Look for "errors" line and "scan" status

Fix:

sh
# If you see checksum errors on a mirrored/RAIDZ pool, ZFS auto-corrects from redundancy. # If errors persist after scrub: # Clear error counters after replacing hardware zpool clear zroot # Check SMART data on the underlying disk smartctl -a /dev/ada0

GELI Encrypted Disk Issues

Diagnose:

sh
# Check GELI status geli status # List GELI providers geli list

Fix -- Unlock a GELI-Encrypted Disk:

sh
# Attach the GELI provider with your key geli attach -k /root/ada1.key /dev/ada1 # If using a passphrase: geli attach /dev/ada1p2 # Mount the unlocked filesystem mount /dev/ada1p2.eli /mnt

If you lost the GELI key and have no backup, the data is unrecoverable. Always keep GELI key backups on separate media.

Disk I/O Errors

Diagnose:

sh
# Check dmesg for disk errors dmesg | grep -i "error\|fault\|fail" | grep -i "ada\|da\|nvd" # Check SMART health smartctl -H /dev/ada0 smartctl -l error /dev/ada0

Fix:

If SMART reports pending sectors or reallocated sectors, plan for disk replacement immediately. Do not wait for a full failure.


5. Performance Problems

For a deep dive, see our FreeBSD performance tuning guide.

High CPU Usage

Diagnose:

sh
# Real-time process view sorted by CPU top -SHP # See which processes consume the most CPU ps aux --sort=-%cpu | head -20 # Check system load averages uptime

Fix:

sh
# Identify the offending process from top # If it is a runaway process: kill -TERM <pid> # If it is a legitimate process consuming too much: # Lower its priority renice 20 -p <pid> # Use cpuset to limit it to specific cores cpuset -l 0-1 -p <pid>

Memory Pressure and Swap

Diagnose:

sh
# Check memory usage sysctl hw.physmem sysctl vm.stats.vm.v_free_count vmstat -h # Check swap usage swapinfo -h # See per-process memory top -o res

Fix:

sh
# If swap is full, find the memory hog: ps aux --sort=-%mem | head -10 # Add emergency swap truncate -s 2G /usr/swap0 chmod 0600 /usr/swap0 mdconfig -a -t vnode -f /usr/swap0 -u 0 swapon /dev/md0 # Tune the ARC cache if ZFS is consuming too much RAM sysctl vfs.zfs.arc_max=2147483648 # Limit ARC to 2 GB # Make it persistent: echo 'vfs.zfs.arc_max="2147483648"' >> /boot/loader.conf

Disk I/O Bottlenecks

Diagnose:

sh
# Real-time I/O statistics iostat -x -w 2 # Per-process I/O (requires DTrace) dtrace -n 'io:::start { printf("%s %d\n", execname, args[0]->b_bcount); }' # Check ZFS I/O zpool iostat -v zroot 2

Fix:

sh
# Enable ZFS prefetch tuning sysctl vfs.zfs.prefetch.disable=0 # Increase ZFS transaction group timeout for write-heavy workloads sysctl vfs.zfs.txg.timeout=10 # Check for fragmented ZFS datasets zpool status -v zroot

For ongoing performance monitoring, set up proper tooling as described in our server monitoring guide.


6. Service Failures

Debugging rc.d Services

Diagnose:

sh
# Check service status service nginx status # List all enabled services service -e # List all available services service -l # Check if the service is enabled in rc.conf sysrc -a | grep nginx

Fix:

sh
# Enable and start a service sysrc nginx_enable="YES" service nginx start # If a service fails to start, run it in debug mode: service nginx onestatus # Check its rc script for debug flags: /usr/local/etc/rc.d/nginx rcvar # Many services support a config test: nginx -t

Checking Logs

Diagnose:

sh
# System messages tail -100 /var/log/messages # Authentication log tail -100 /var/log/auth.log # Service-specific logs (common locations): tail -100 /var/log/nginx/error.log tail -100 /var/log/maillog tail -100 /var/log/daemon.log # Real-time log watching tail -f /var/log/messages

Permission Issues

Diagnose:

sh
# Check ownership and permissions on the service's files ls -la /usr/local/etc/nginx/ ls -la /var/run/nginx.pid ls -la /var/log/nginx/ # Check if the service user exists id www

Fix:

sh
# Fix ownership for a service chown -R www:www /var/log/nginx chmod 755 /var/log/nginx # If /var/run is missing the PID directory mkdir -p /var/run/nginx chown www:www /var/run/nginx

7. Kernel Panics and Crashes

Reading Crash Dumps

Diagnose:

sh
# Check if crash dumps are enabled sysctl kern.dumpon # After a panic, check for dump files ls -la /var/crash/ # Read the crash dump summary cat /var/crash/info.last # Full analysis requires kernel debug symbols: kgdb /usr/lib/debug/boot/kernel/kernel.debug /var/crash/vmcore.last

Fix -- Enable Crash Dumps for Future Diagnosis:

sh
# Point dumps at a swap partition or zvol sysrc dumpdev="AUTO" # Or specify a device explicitly sysrc dumpdev="/dev/ada0p3" # Enable savecore to save dumps on boot sysrc savecore_enable="YES"

Analyzing dmesg

sh
# View the full kernel message buffer dmesg # Search for errors dmesg | grep -i "panic\|fatal\|error\|fail" # Save dmesg to a file for analysis dmesg > /tmp/dmesg_output.txt

DTrace for Live Debugging

DTrace is one of FreeBSD's most powerful diagnostic tools. See our DTrace tutorial for a thorough introduction.

sh
# Trace system calls by process name dtrace -n 'syscall:::entry /execname == "nginx"/ { @[probefunc] = count(); }' # Trace file opens system-wide dtrace -n 'syscall::open:entry { printf("%s %s", execname, copyinstr(arg0)); }' # Watch for processes being killed dtrace -n 'proc:::exit { printf("%s (pid %d) exited with %d", execname, pid, args[0]); }'

8. Authentication Issues

Locked User Accounts

Diagnose:

sh
# Check if the account is locked pw usershow <username> # Look for failed login attempts grep <username> /var/log/auth.log | tail -20

Fix:

sh
# Unlock the account pw unlock <username> # Reset the password passwd <username> # If using pam_tally or similar, reset the counter # Check PAM configuration: cat /etc/pam.d/system

SSH Key Problems

Diagnose:

sh
# Test SSH with verbose output ssh -vvv user@host # Check sshd logs tail -50 /var/log/auth.log | grep sshd # Check sshd configuration sshd -T | grep -i "pubkey\|authorized\|permit"

Fix:

sh
# Fix permissions (SSH is strict about this) chmod 700 /home/user/.ssh chmod 600 /home/user/.ssh/authorized_keys chown -R user:user /home/user/.ssh # Ensure sshd allows key auth grep -i pubkeyauthentication /etc/ssh/sshd_config # Should be: PubkeyAuthentication yes # Restart sshd after config changes service sshd restart

sudo / doas Configuration

Diagnose:

sh
# Check if the user is in the wheel group id <username> # Test sudo sudo -l -U <username>

Fix:

sh
# Add user to wheel group pw groupmod wheel -m <username> # For doas, create or fix /usr/local/etc/doas.conf echo "permit :wheel" > /usr/local/etc/doas.conf chmod 600 /usr/local/etc/doas.conf # For sudo, use visudo to edit the sudoers file safely visudo # Uncomment: %wheel ALL=(ALL:ALL) ALL

9. Jail Problems

FreeBSD jails are a core feature for isolation and multi-tenancy. Our jails guide covers creation and management.

Jail Networking Issues

Diagnose:

sh
# Check jail network configuration jls # From inside the jail, check the interface jexec <jail_name> ifconfig # Verify the jail can reach the network jexec <jail_name> ping -c 3 8.8.8.8

Fix:

sh
# If using VNET jails, ensure the epair interface is up: ifconfig epair0a up jexec <jail_name> ifconfig epair0b up # Set DNS inside the jail echo "nameserver 1.1.1.1" > /path/to/jail/etc/resolv.conf # For NAT-based jails, check the PF rules: pfctl -sr | grep nat

Package Management Inside Jails

Diagnose:

sh
# Enter the jail and check pkg status jexec <jail_name> pkg info # Check if DNS works (required for pkg) jexec <jail_name> host pkg.FreeBSD.org

Fix:

sh
# Bootstrap pkg inside a new jail jexec <jail_name> pkg bootstrap -y # If pkg repos are not accessible, copy the host's resolv.conf cp /etc/resolv.conf /jails/<jail_name>/etc/resolv.conf # Update packages inside the jail jexec <jail_name> pkg update && jexec <jail_name> pkg upgrade

Jail Resource Limits

Diagnose:

sh
# Check current resource limits with rctl rctl -a jail:<jail_name> # Check running jail parameters jls -j <jail_name> -v

Fix:

sh
# Enable RACCT/RCTL in loader.conf (requires reboot) echo 'kern.racct.enable=1' >> /boot/loader.conf # Set memory limit for a jail rctl -a jail:<jail_name>:memoryuse:deny=2G # Set CPU percentage limit rctl -a jail:<jail_name>:pcpu:deny=50 # Make limits persistent in /etc/jail.conf or your jail manager's config

10. System Recovery

When nothing else works, you need a recovery path.

Boot Environment Rollback

This is the fastest recovery method if you use ZFS boot environments (and you should):

sh
# From the loader prompt, list boot environments bectl list # Activate a previous environment bectl activate <known_good_be> reboot

See our boot environments guide for setup and best practices.

Live USB Recovery

When you cannot boot at all:

  1. Download a FreeBSD installation ISO and write it to USB:
sh
# From another machine dd if=FreeBSD-14.2-RELEASE-amd64-memstick.img of=/dev/da0 bs=1m conv=sync
  1. Boot from the USB and select "Live CD" or "Shell".
  1. Import your ZFS pool:
sh
# Discover and import the pool zpool import zpool import -f zroot # Mount the boot environment mount -t zfs zroot/ROOT/default /mnt # Now you can edit files: vi /mnt/boot/loader.conf vi /mnt/etc/rc.conf vi /mnt/etc/fstab
  1. Export and reboot:
sh
zpool export zroot reboot

Manual fsck from Live USB

For UFS systems that will not mount:

sh
# From the live USB shell fsck -y /dev/ada0p2 # If the superblock is damaged, try alternate superblocks fsck -b 32 /dev/ada0p2 # After repair, mount and verify mount /dev/ada0p2 /mnt ls /mnt

Recovering a Broken rc.conf

If a bad rc.conf entry prevents boot:

sh
# From single-user mode: mount -u / mount -a # Edit rc.conf vi /etc/rc.conf # Or use sysrc to remove the bad entry sysrc -x bad_variable_enable

11. Useful Diagnostic Commands

Quick reference table for the most common diagnostic commands on FreeBSD:

| Task | Command |

|---|---|

| System info | uname -a |

| Uptime and load | uptime |

| CPU usage (live) | top -SHP |

| Memory usage | vmstat -h |

| Swap usage | swapinfo -h |

| Disk space | df -h |

| ZFS pool status | zpool status |

| ZFS dataset usage | zfs list |

| Disk I/O | iostat -x -w 2 |

| Network interfaces | ifconfig -a |

| Open ports | sockstat -l |

| Routing table | netstat -rn |

| Firewall rules | pfctl -sr |

| DNS test | drill freebsd.org |

| All listening services | sockstat -4 -l |

| Kernel messages | dmesg |

| Boot messages (full) | dmesg -a |

| Hardware list | pciconf -lv |

| USB devices | usbconfig list |

| SMART disk health | smartctl -H /dev/ada0 |

| Process tree | ps auxww --forest |

| Jail list | jls |

| Boot environments | bectl list |

| Enabled services | service -e |

| Package audit | pkg audit -F |

| Check pkg deps | pkg check -d -a |

| System logs | tail -f /var/log/messages |

| Auth logs | tail -f /var/log/auth.log |

| GELI status | geli status |

| Active mounts | mount |

For monitoring these metrics over time, see our FreeBSD server monitoring guide.


12. Frequently Asked Questions

How do I recover from a bad kernel update?

Boot into the loader prompt and load the previous kernel:

sh
unload set kernel="kernel.old" boot

FreeBSD keeps the previous kernel as kernel.old after every upgrade. Once booted, you can use bectl to roll back the boot environment or re-run the update. See our FreeBSD update guide for the recommended update workflow.

My ZFS pool says DEGRADED but all disks are present. What do I do?

This usually means ZFS detected errors on a disk even though the disk is physically present. Run:

sh
zpool status -v zroot zpool scrub zroot # Wait for the scrub to complete zpool status zroot

If errors remain after scrub, check smartctl -a /dev/adaX on the affected disk. A disk can be physically present but failing. Replace it proactively. More on this in our ZFS guide.

How do I find out why a service failed to start?

Three steps:

sh
# 1. Check the service status and rc script service <name> status service <name> rcvar # 2. Try starting it manually and watch stderr /usr/local/etc/rc.d/<name> onestart # 3. Check the logs tail -50 /var/log/messages tail -50 /var/log/daemon.log # Check service-specific log location from the service's config file

How do I reset the root password if I forgot it?

Boot into single-user mode (option 2 at the boot loader), then:

sh
# Mount root read-write mount -u / mount -a # Reset the password passwd root # Reboot reboot

If single-user mode also requires a password (because you set kern.securelevel), you need to boot from a live USB and edit /mnt/etc/master.passwd directly, then run pwd_mkdb -p /mnt/etc/master.passwd.


Final Notes

The best troubleshooting is prevention. Keep your system updated with regular freebsd-update runs, maintain ZFS boot environments before every upgrade, monitor disk health with SMART, and keep logs rotated and readable. When something does break, work methodically: check logs first, isolate the component, test one change at a time.

For ongoing system health, combine the diagnostic commands above with a proper monitoring stack as described in our monitoring guide. For performance baselines, see our performance tuning guide. And for keeping your system current, follow our update guide.

Get more FreeBSD guides

Weekly tutorials, security advisories, and package updates. No spam.