You see the security advisory. Critical severity, CVSS score through the roof, exploit code already public. You run the update command and wait.
Then everything breaks.
Patching should be simple, but in practice it's where theory meets a mess of dependency chains, custom kernels, and services that refuse to restart. I've walked dozens of site owners through these failures, and seven errors account for most of the pain. Here's how to diagnose and fix each one.
Error 1: Package dependency conflicts
You run yum update or apt upgrade and hit a wall of unmet dependencies. The package manager refuses to proceed because updating one library would break three other packages.
Symptoms:
Error: Package: app-1.2.3 requires libfoo.so.5
Removing: libfoo-5.4.1 (installed)
Updated By: libfoo-6.0.1 (updates)
The root cause is version pinning or third-party repositories that haven't caught up to your base distribution's package versions. Your custom-compiled application links against an older library, and the security patch bumps the library to a new major version.
Fix it:
First, identify what's holding back the update:
yum deplist <package-name> | grep dependency
# or on Debian/Ubuntu:
apt-cache depends <package-name>
You have three options. One: exclude the conflicting package temporarily and patch everything else.
yum update --exclude=libfoo
Two: check if the third-party vendor has released an updated version that works with the new library. Visit their repository or mailing list.
Three: if the conflicting application isn't critical, remove it, apply the patch, then reinstall a compatible version. I've seen hosting environments where a deprecated monitoring agent blocked kernel updates for months.
Error 2: Kernel update triggers boot failure
The patch includes a kernel update. You reboot and the server never comes back. This one is terrifying because you can't SSH in to fix it.
Symptoms:
Server becomes unreachable after reboot. If you have console access, you see a kernel panic, initramfs prompt, or a boot loop at the GRUB menu.
Root cause:
Missing kernel modules (especially for RAID controllers or network cards), corrupted initramfs, or a bootloader that wasn't updated to point to the new kernel.
Fix it:
Boot the old kernel. At the GRUB menu (press Esc or Shift during boot to see it), select "Advanced options" and choose the previous kernel version. If GRUB doesn't appear, you'll need console access through your hosting panel or IPMI.
Once booted into the old kernel, rebuild the initramfs for the new kernel:
# CentOS/RHEL/AlmaLinux:
dracut -f /boot/initramfs-$(uname -r).img $(uname -r)
# Ubuntu/Debian:
update-initramfs -u -k all
Verify that GRUB knows about the new kernel:
grub2-mkconfig -o /boot/grub2/grub.cfg
# or on Debian/Ubuntu:
update-grub
Reboot again. If it still fails, check /var/log/messages or journalctl -xb from the old kernel to see what module is missing. You might need to install kernel headers or rebuild a custom driver.
In support tickets I handled, the usual culprit was a RAID controller driver that wasn't included in the default initramfs. Adding it to /etc/dracut.conf.d/ fixed future updates.
Error 3: Service fails to restart after library update
The patch completes without errors, but when you restart Apache, MySQL, or another service, it crashes immediately or refuses to start.
Symptoms:
systemctl restart httpd
Job for httpd.service failed. See 'systemctl status httpd' and 'journalctl -xe' for details.
Status shows "code=exited, status=127" or a segmentation fault.
Root cause:
The service is still using old library versions loaded into memory. Or a configuration directive is no longer valid in the updated version of the software.
Fix it:
First, check which processes are using outdated libraries:
sudo checkrestart
# or manually:
lsof | grep DEL | grep lib
Restart those services. For web servers and databases, schedule a maintenance window because this will drop connections.
If the service still won't start, read the actual error:
systemctl status httpd -l
journalctl -u httpd -n 50
Look for lines like "undefined symbol" or "cannot open shared object file." That tells you which library is missing or incompatible.
Run ldd on the binary to see what it's trying to link:
ldd /usr/sbin/httpd
If a library shows "not found," you might need to run ldconfig to update the linker cache, or reinstall the package that provides that library.
For configuration errors, compare your current config against the package's new default. Check the changelog:
rpm -q --changelog httpd | head -30
# or:
zcat /usr/share/doc/apache2/changelog.Debian.gz | head -30
Deprecated directives get flagged. Comment them out or replace them.
Error 4: Out-of-disk-space during update
The update starts, downloads packages, then fails mid-installation with a cryptic error about write failures or no space left on device.
Symptoms:
Error: Disk Requirements:
At least 250MB more space needed on the / filesystem.
Or the update appears to succeed but leaves the system in a broken state because some files didn't finish writing.
Root cause:
/boot is full of old kernels, /var/cache is bloated, or log files have grown unchecked.
Fix it:
Check disk usage immediately:
df -h
du -sh /var/cache/* /boot/* /var/log/* | sort -h
For a full /boot, remove old kernels. Keep the current one and one fallback:
# CentOS/RHEL:
package-cleanup --oldkernels --count=2
# Ubuntu/Debian:
apt autoremove --purge
Clear package manager caches:
yum clean all
# or:
apt clean
Rotate or truncate huge log files:
logrotate -f /etc/logrotate.conf
# or manually:
> /var/log/messages
Once you've freed space, retry the update. If the previous attempt left packages half-installed, repair them first:
yum-complete-transaction
# or:
dpkg --configure -a
apt --fix-broken install
Error 5: GPG key verification fails
The package manager refuses to install the update because it can't verify the package signature.
Symptoms:
Warning: Signature not found for package-1.2.3.rpm
Public key for package-1.2.3.rpm is not installed
Or on Debian:
W: GPG error: repository Release: The following signatures couldn't be verified
Root cause:
The repository's GPG key has expired, been rotated, or was never imported. This happens often with third-party repos like EPEL, Remi, or vendor-specific package sources.
Fix it:
Import the updated key. Repository documentation usually provides the command:
rpm --import https://example.com/RPM-GPG-KEY-repo
# or:
curl -fsSL https://example.com/key.asc | sudo gpg --dearmor -o /usr/share/keyrings/repo.gpg
If you're certain the package is legitimate and need to bypass the check temporarily:
yum update --nogpgcheck
# or:
apt -o Acquire::AllowInsecureRepositories=true update
Don't make this a habit. Fix the key properly.
So what if the patch itself is broken?
Sometimes the vendor's patch introduces new bugs or breaks functionality. You need to roll back.
Symptoms:
Application errors, performance degradation, or test failures immediately after patching. Your monitoring lights up, and downgrading fixes it.
Root cause:
Regression in the patched code, or the patch wasn't tested against your specific configuration.
Fix it:
Downgrade the package to the previous version. On RHEL/CentOS:
yum history list
yum history undo <transaction-id>
Or downgrade a specific package:
yum downgrade package-name-old-version
On Debian/Ubuntu, if you have the old .deb in /var/cache/apt/archives/:
apt install /var/cache/apt/archives/package_old-version_amd64.deb
Then hold the package to prevent automatic updates until a fixed version arrives:
yum versionlock package-name
# or:
apt-mark hold package-name
Report the regression to the vendor with logs and reproduction steps. They'll usually release a corrected patch within days.
Error 7: SELinux blocks the patched binary
After patching, the service starts but certain operations fail with "Permission denied" even though file permissions look correct.
Symptoms:
ls -l /usr/sbin/httpd
# shows correct permissions
systemctl status httpd
# shows running
# but:
tail /var/log/httpd/error_log
# Permission denied: AH00072: make_sock: could not bind to address
Root cause:
SELinux policy hasn't been updated for the new binary. The patched executable has a different hash and SELinux treats it as untrusted.
Fix it:
Check for SELinux denials:
sudo ausearch -m avc -ts recent
# or:
sudo grep denied /var/log/audit/audit.log
You'll see lines like "denied { bind } for pid=1234 comm='httpd'".
Restore the default context on the binary:
restorecon -Rv /usr/sbin/httpd
If that doesn't work, the policy itself needs updating. Generate a custom policy from the denials:
grep denied /var/log/audit/audit.log | audit2allow -M mypolicy
semodule -i mypolicy.pp
Restart the service and test. If you're still stuck, temporarily set SELinux to permissive for that service only:
semanage permissive -a httpd_t
Don't leave it permissive. File a bug with your distribution so the official policy gets fixed.
What to check first
Before you patch anything, take a snapshot or backup. Most hosting panels and VPS providers offer one-click snapshots. Use them.
Test the patch on a staging server that mirrors production. If you don't have staging, at least read the changelog and check for known issues in the vendor's bug tracker.
Schedule patching for low-traffic windows. Critical CVEs are urgent, but a midnight patch is easier to roll back than one at 2 PM.
After patching, verify that your applications still work. Don't just check that services are running—load your site, hit your API endpoints, tail your logs for errors. I've seen patched systems that appeared healthy but were silently failing backend jobs.
Keep your monitoring tight during the first hour after a patch. Set up alerts for increased error rates, latency spikes, or service restarts.
Does every security patch require a reboot?
No. Kernel, glibc, and some low-level library patches do. Most application-level patches just need a service restart. Check the advisory or run needs-restarting on RHEL-based systems to see what must restart.
Can I automate patching safely?
For non-critical environments, yes. Use yum-cron or unattended-upgrades to apply security patches automatically. For production, automate staging patches but keep production manual until you've verified.
What if the patch needs a dependency from a repo I don't have enabled?
Enable the repo temporarily with --enablerepo= for that transaction only, or add it permanently if it's an official repo like EPEL. Avoid enabling untrusted third-party repos without vetting them.
Should I patch immediately or wait for others to test?
If exploits are public and your service is internet-facing, patch immediately. If the CVE is theoretical or requires local access, you can wait 24-48 hours to see if regressions surface. Monitor security mailing lists and issue trackers.
Double-check these before every patch
Free disk space in /, /boot, and /var. Clear old kernels and logs if needed.
Snapshot or backup your system. Test the rollback procedure.
Read the changelog. Look for breaking changes, deprecated features, or known issues.
Verify your monitoring and alerting are active. You want to know immediately if something breaks.
Have console access ready. If SSH breaks, you need a way in.
Patching critical vulnerabilities is not optional, but doing it right means preparing for failure. These seven errors are fixable if you catch them fast and know where to look.
![Critical CVE Vulnerabilities: 7 Patch Errors [Solved]](/images/blog/critical-cve-vulnerabilities-7-patch-errors-solved.jpg)