Panellicense

Fix cPanel update failures: upcp exit 256, blockers, locks

The upcp failure email tells you almost nothing. Here is the order to check things — update log, package stage, blockers, disk space, and stale locks.

cPAll cPanel articlesTroubleshooting5 min readUpdated 2026-09-02
schema: HowToschema: FAQPage

The notification reads "Maintenance ended; however, it did not exit cleanly (256). The following events were logged: 'scripts/update-packages'." It names the stage that failed and nothing else. Meanwhile the server keeps running the old build, the failure repeats every night, and the mail gets filtered into a folder nobody opens.

Work through these in order. The first two cover most of what actually happens on a production fleet.

Read the log before you touch anything

Every run writes /var/cpanel/updatelogs/update.<unix timestamp>.log, and last symlinks to the most recent one:

tail -60 /var/cpanel/updatelogs/last
grep -Ei 'fatal|blocker|failed|did not exit cleanly' /var/cpanel/updatelogs/last | tail -20
/usr/local/cpanel/cpanel -V

The version output tells you whether you are behind at all — compare it against the tier you are subscribed to in cPanel's update tiers. A server on RELEASE that is two majors back has been failing for months, not days.

Stage: scripts/update-packages

This is the OS package stage, not cPanel's own code. upcp shelled out to dnf (or yum on EL7), the transaction failed, and cPanel reported the non-zero exit. Reproduce it directly — the real error is in the package manager's output, not cPanel's:

dnf clean all
dnf -y update

Typical causes, in the order they show up: a third-party repo (Remi, IUS, an old ELevate leftover) offering a conflicting version, a GPG key that expired, or a mirror returning 403 because the OS release is EOL. Remove or pin the offending repo, then repair cPanel's own package set and re-run:

/usr/local/cpanel/scripts/check_cpanel_pkgs --fix
/usr/local/cpanel/scripts/upcp --cron

Stage: the update never started

If the log ends within seconds and mentions a blocked version change, a blocker fired. The ones that come up in practice:

BlockerFix
Invalid or expired licenseDiagnose the license error, then renew your cPanel license
OS past cPanel's support windowMove CentOS 7 to AlmaLinux
MySQL/MariaDB below the new minimumUpgrade the database in WHM
Invalid mailserver or ftpserver value in /var/cpanel/cpanel.configSet them to a valid value (dovecot; pure-ftpd or proftpd)
Account transfer in progressFinish or abort it in WHM → Transfers → Review Transfers and Restores

Blockers cannot be overridden, and --force does not bypass them. An in-flight transfer is the one that catches people out — a stalled restore from the Transfer Tool holds updates off indefinitely until someone clears it.

Disk space, inodes, and read-only mounts

A major upgrade needs a few GB free; 3 GB on /usr is a sane floor, and /var needs room for the staged files.

df -h /usr /var /tmp
df -i /usr /var
mount | grep -E ' (ro|read-only)'
du -sh /usr/local/cpanel/logs/archive /usr/local/apache/logs/archive

Archived logs and core dumps are the usual offenders. Inode exhaustion produces the same failure with plenty of gigabytes still showing — check both.

Stuck runs and stale locks

If upcp reports that maintenance is already running but nothing is progressing, confirm before you intervene:

ps auxf | grep -E 'upcp|updatenow' | grep -v grep
stat -c '%y' /var/cpanel/updatelogs/last

A log whose mtime has not moved in 30 minutes with no live process is a stale run. Clear it by re-running in a terminal multiplexer so an SSH drop cannot orphan it again:

tmux new -s upcp
/usr/local/cpanel/scripts/upcp --force

--force reinstalls the current version and upgrades regardless of preferences. --sync repairs the installed version without pulling a newer one — that is the safer first attempt when you suspect a partial install rather than a missed upgrade.

After an OS major upgrade

If the server was ELevated or otherwise moved between EL major versions, check that cPanel knows what it is running on:

grep rpm_dist_ver /var/cpanel/sysinfo.config

rpm_dist_ver=unknown makes every subsequent update fail at the package stage. Regenerate the file and re-run the update:

/usr/local/cpanel/scripts/gensysinfo
/usr/local/cpanel/scripts/upcp --cron
What does 'did not exit cleanly (256)' mean in cPanel?+
Exit 256 is a generic non-zero status from a sub-stage of upcp. The named event — usually scripts/update-packages — tells you which stage failed; the reason is in /var/cpanel/updatelogs/last, not in the email.
Where are cPanel update logs stored?+
/var/cpanel/updatelogs/, one file per run named update.<unix timestamp>.log, with a 'last' symlink pointing at the most recent run.
Is it safe to run /scripts/upcp --force?+
Yes, but treat it as a second attempt rather than a first move. It reinstalls the current version and ignores your update preferences, so it fixes partial installs but hides the underlying cause. Run it in tmux or screen — a dropped SSH session mid-run leaves the install inconsistent.
Why does my cPanel update keep failing every night?+
The daily cron re-runs the same failing step. Nothing self-heals: a blocker, a broken repo, or a full disk will reproduce indefinitely until you fix it, so the age of the first failure email is a good measure of how far behind the server is.
Can I disable automatic cPanel updates while I fix this?+
Set UPDATES=manual in /etc/cpupdate.conf to stop the unattended run. Leave the hourly security patch mechanism alone — it applies critical fixes to your current version independently of the tier.

Next steps

Switch in an afternoon

Switch from your current reseller — free.

We migrate active cPanel, Plesk, LiteSpeed and CloudLinux licenses from any reseller. We prorate the first month so you never pay twice, and your customers see zero downtime during the swap.