Skip to main content

4 posts tagged with "cPanel"

View all tags

AlmaLinux 10 + cPanel: New-Server Pitfalls from TFA to DNS

Β· 9 min read

cPanel 138 on AlmaLinux 10 installs smoothly and the panel opens β€” the real traps cluster in the close-out phase: security hardening, panel asset repairs, and domain mounting, each with counter-intuitive behavior waiting.

Encountered this while hardening a production cPanel server for a client β€” all three failure classes showed up during the close-out of the same AlmaLinux 10 machine. This post breaks them down by scenario.

TL;DR​

Three scenarios, three "looks right, does nothing" traps: TFA configured but login never asks for a code β€” the policy-wide switch is off, so per-user configuration is inert; frontend assets that look "missing" must be verified against the official manifest first β€” some never existed on that cpanelsync tree, and some are skipped because a polluted digest cache lets upcp fake success; Park domains rejected by the NS ownership check β€” when DNS lives on a cloud provider, the userdata include injecting a ServerAlias is the supported path.

Scenario one: "missing" WHM frontend libraries β€” verify before fixing​

While triaging panel oddities, /usr/local/cpanel/base/libraries turns out not to exist β€” do not rush to repair a defect. Upstream cPanel 138 simply has no such path. The real homes of the shared frontend libraries:

  • base/frontend/jupiter/libraries/ β€” a symlink farm pointing at ../../../../3rdparty/share/<lib>, distributed by jupiter's own cpanelsync tree (sortablejs, ui-fonts, fontawesome, cldr)
  • base/unprotected/libraries/ β€” same mechanism, hosting legacy libraries

To decide whether a file is genuinely missing, pull the official manifest instead of trusting one path:

curl -sO http://httpupdate.cpanel.net/cpanelsync/138/<tree>/.cpanelsync.bz2
bzcat .cpanelsync.bz2 | grep <target-path>
# Entry format: d===./path===755 (directory)
# l===./link-name===777===target (symlink)

Second rule: base/ is not entirely cpanelsync-distributed. The v138 cpanel-* RPMs (bootstrap5, ace-editor, sortablejs and friends) install libraries directly into /usr/local/cpanel/3rdparty/share/<lib>/<version>, and cpanelsync only lays the symlinks into the theme trees. Verify the RPM side with rpm -V <package> and the cpanelsync side with the manifest β€” both.

If files are confirmed missing but upcp --sync reports success without restoring them, suspect the digest caches: /usr/local/cpanel/.cpanelsync.digest and the per-theme-tree digests. When an interrupted update pollutes them, --sync skips the missing files and still exits 0. Delete the affected digest and run upcp --force for a full reconciliation.

A successful --sync is not proof of complete files β€” judge by actual page loading: drive a headless Chromium to collect console errors and requests at 4xx or above; that is more honest than any exit code.

Two more operational traps on hardened machines:

  • For root access, prefer the cloud assistant (aliyun ecs RunCommand) β€” out-of-band, SSH-free, audited by default. Pass the instance via --InstanceId.1 and feed CommandContent the raw script, not base64. Any temporary sudoers grant needs a self-cleaning /etc/cron.d entry; after cleanup, sudo -n whoami must answer a password is required to confirm the revoke took.
  • Bulk-probing cpsrvd triggers rate limiting: a shell loop of individual curl calls degrades to all-000 responses after a few dozen requests, which reads like a mass 404. A single curl process fetching multiple URLs over keepalive behaves normally. And pkill -f matches your own bash -c command line β€” use the [] character-class trick or a plain PID.

A 200 from a WHM page does not mean an authenticated session β€” the login page returns 200 too. Assert on the <title> or a body fingerprint (the Two-Factor Authentication page's title, for instance).

Scenario two: the hardening chain of traps​

The goal: no root over SSH, TFA on the panel, a minimal sudo whitelist. Every step hides a precondition.

The TFA policy switch is a precondition. After twofactorauth_set_tfa_config writes a user's secret, the login form may never show the code step β€” twofactorauth_policy_status must report is_enabled = 1 (enabled via twofactorauth_enable_policy), otherwise WHM validates password only. Verified in a browser: before the policy, the password logs straight in; after, an "Enter the security code" page appears.

Two CLI details for TFA: the token parameter of twofactorauth_set_tfa_config is tfa_token, not code (passing code silently fails with "security code is invalid"); and the TOTP must be computed against the server clock β€” a 23-second skew crosses the window and the locally computed code is always rejected. The secret lands in /var/cpanel/authn/twofactor_auth/tfa_userdata.json.

The supported API path without root SSH is session plus cpsess prefix. After create_user_session and a curl cookie-jar login, API calls must carry the cpsess path: https://host:2087/cpsessNNN/json-api/<function>; hitting /json-api/ directly answers "Token denied". The service parameter of create_user_session is whostmgrd (with the d) β€” whostmgr and cpanel are rejected; only cpaneld, webmaild, whostmgrd are valid.

sudoers matches the entire command sequence exactly. Even the position of --output=json and the argument order are locked; any edit to the caller's command silently degrades to password authentication β€” which, with the opsuser password locked, is an outright refusal. Changing the command means changing the matching sudoers file.

Three whmapi1 details: the real path is /usr/local/cpanel/bin/whmapi1 (prefer it over the symlink); the default output is YAML, so --output=json before jq; and sethostname takes hostname, not domain β€” domain= silently passes an empty value and runs to no effect, and cPanel refuses whm./cpanel./webmail.-prefixed hostnames. On machines with the DNS role disabled, the trailing dnsadmin socket "Connection refused" is expected and harmless; after a rename, create_user_session URLs follow the new hostname automatically, and AutoSSL reissues the cpsrvd certificate within about a minute.

sshd drop-ins: first value wins. The Include sshd_config.d/*.conf in AlmaLinux's main sshd_config sits at the top, so drop-ins parse before the main body and sshd keeps the first occurrence β€” that is how a drop-in overrides the main file; among drop-ins, filename sort order decides (000- sorts before 00-). After any change: sshd -t, then sshd -T | grep -E 'permitrootlogin|passwordauthentication|allowusers' to confirm the effective values before reloading.

Host Access Control does nothing here. cPanel 138 + AlmaLinux 10 ships a cpsrvd that does not link libwrap (tcp_wrappers is gone from RHEL-line distributions); rules written to /etc/hosts.allow and a cpsrvd restart changed nothing in testing. Layer-3/4 allowlists belong in firewalld rich rules; leaving hosts.allow in place is harmless β€” it activates automatically if libwrap ever returns.

Three AlmaLinux 10 verification blind spots: last is always empty β€” systemd 256 dropped wtmp, login records live only in the journal (journalctl -u sshd as root); opsuser cannot execute /usr/bin/su (denied at the exec layer), so the root password can only be verified through a WHM form or the console; and /etc/ssh/sshd_config.d/, /etc/cron.d/* (mode 600), /var/cpanel/authn/ are unreadable to opsuser β€” hardening audits must run in WHM Terminal or VNC.

Scenario three: domain NS lives elsewhere, alias mounting rejected​

uapi Park park domain=test.xxx is refused: the domain's nameservers (hosted on a cloud DNS) are "not associated with this server" β€” cPanel validates that the domain's authoritative NS points at the machine, and in common China-hosting setups DNS lives on the provider, so this check can never pass.

The supported path, without touching the domain's NS, is a userdata include injecting a ServerAlias:

# one for http, one for https
/etc/apache2/conf.d/userdata/std/2_4/<user>/<domain>/alias.conf
/etc/apache2/conf.d/userdata/sssl/2_4/<user>/<domain>/alias.conf

(The ssl-side directory name varies by version β€” sssl/2_4 here, sometimes written ssl/2_4; trust the uncommented include line in httpd.conf.) Contents, one line:

ServerAlias test.xxx

Then /scripts/rebuildhttpdconf. A wrong directory name leaves the include line commented out β€” silently inert. Verify by inspecting whether the Include "...userdata..." lines in httpd.conf carry a comment prefix.

Confirm routing with httpd -S and by watching which vhost's domlog receives the requests.

One linkage note: domains attached via ServerAlias are not managed by AutoSSL, so no certificate is issued for them automatically β€” see cPanel AutoSSL Not Issuing? The Exclusion List and vhost Paths.

Warnings

  • Hardening steps have order dependencies: enable the TFA policy switch before configuring user secrets; confirm the sudoers whitelist command works before disabling root SSH β€” inverted order locks you out.
  • Never declare a file missing without diffing the official manifest and checking the RPM side β€” two distribution channels, both must be cleared.
  • Configuration file content is not runtime behavior: after drop-in edits, read the effective values from sshd -T.

Frequently Asked Questions​

Why is ssh PermitRootLogin no not working?​

Because sshd takes the first value it parses. On AlmaLinux the Include directive sits at the top of the main sshd_config, so drop-in files under sshd_config.d/ are parsed before the main body β€” a drop-in overrides the main file, and among drop-ins the lexicographically first filename wins. Always verify with sshd -t followed by sshd -T | grep permitrootlogin to see the effective value before reloading.

How does WHM two-factor authentication work?​

Two layers must both be active: the server-wide policy switch (twofactorauth_enable_policy) and the per-user TOTP secret (twofactorauth_set_tfa_config). With the policy off, WHM keeps validating password only even when a secret exists. When configuring via CLI, the token parameter is tfa_token β€” not code β€” and the TOTP must be computed against the server clock; a skew of just 20-odd seconds crosses the window and gets rejected.

Why is my Apache ServerAlias not working on cPanel?​

The userdata include is most likely inert: a wrong directory name leaves the Include line commented out in httpd.conf, and the alias never loads. ServerAlias files belong in /etc/apache2/conf.d/userdata/std/2_4/<user>/<domain>/ and the ssl counterpart, followed by /scripts/rebuildhttpdconf. Verify by checking whether the Include userdata lines in httpd.conf carry a comment prefix, then confirm with httpd -S and the vhost domlogs.

CCLEE

Independent developer, 24 years in e-commerce, focused on grounding AI in real business scenarios.

Work with me

cPanel Restore Shows Default Page? Aliyun ECS NAT IP Fix

Β· 6 min read

Restoring a cPanel account from a cpmove archive on an Aliyun ECS instance: restorepkg reports success, httpd -S shows the namevhosts β€” and the browser greets every domain with the server's default page.

Encountered this while migrating a client's two China sites into a cPanel environment on Aliyun China β€” the very first public verification after the restore ran into this cloud architecture trap.

TL;DR​

On Aliyun ECS the NIC only carries a private IP; the public IP is edge NAT and never lands on the machine. Vhosts migrated from the old server bind that non-existent public address, never match at runtime, and all traffic drops into the wildcard default vhost. Fix all three IP stores (/etc/wwwacct.conf, /var/cpanel/users/, /var/cpanel/userdata/) and rebuild httpd.conf; write the private IP into /etc/mainip so new accounts start correct.

Symptoms​

Every migration step looks clean: restorepkg finishes without errors and the namevhosts are right there in the Apache config. But public verification falls flat β€” every domain lands on the same defaultwebpage redirect, and the site's domlog stays empty forever.

The clincher is a single static-file request: fetch a file that certainly exists and was never touched (say /some-real-page.html) and it returns 404 β€” with the error page styled from /var/www/html/*.shtml, the cPanel default site's directory. The real document root never received the request.

$ httpd -S | grep example.cn
203.0.113.10:80 example.cn ...

The vhost binds 203.0.113.10 β€” the old server's public IP. This new machine's NIC has no such address.

Root causes​

The public IP is not on the machine. hostname -I returns only a private address like 172.28.100.10. Aliyun ECS public IPs are edge NAT: traffic arrives at Alibaba's gateway and is forwarded to the instance's private address β€” the public IP never appears on the NIC.

The restore inherited the old IP verbatim. The old server was a classic VPS with the public IP on the NIC, so its vhosts record exactly that address. cpmove brings the configuration over as-is, and every vhost Address now points at an address that does not exist locally.

Apache matches vhosts by IP:port. Requests arrive, match no namevhost, and fall into the *:80 default vhost (DocumentRoot /var/www/html). That single mechanism explains all three symptoms: the default page, the empty domlog, and the mismatched 404 styling.

Fix​

1. Confirm the NAT setup. One command:

hostname -I
# 172.28.100.10 ← private segment only: NAT confirmed

2. Rewrite all three IP stores β€” all of them, no exceptions. cPanel keeps IP information in three places serving different flows. Fixing only userdata rebuilds the vhosts correctly, but a stale wwwacct.conf writes the wrong address into every future account.

# 2a. Global default (read by account creation)
sed -i 's/^ADDR=.*/ADDR=172.28.100.10/' /etc/wwwacct.conf

# Default IP for new accounts β€” set this too
echo 172.28.100.10 > /etc/mainip

# 2b. Per-account record
sed -i 's/^IP=.*/IP=172.28.100.10/' /var/cpanel/users/example

# 2c. Bulk rewrite of userdata β€” the only input rebuildhttpdconf trusts
cd /var/cpanel/userdata/example
for f in *; do
[ -f "$f" ] && sed -i 's/^ip: .*/ip: 172.28.100.10/' "$f"
done

The [ -f "$f" ] guard is not decorative: the userdata directory mixes in socket files like scope, and sed errors out on them without the check.

3. Rebuild and restart.

/scripts/rebuildhttpdconf
/scripts/restartsrv_httpd

4. Verify. httpd -S should now show namevhosts on the private IP; from the server, a request with an explicit Host header tells you which vhost answers:

curl -s -H "Host: example.cn" http://172.28.100.10/some-real-page.html -o /dev/null -w "%{http_code}\n"
# 200 ← no longer the default vhost's 404

Finish with an external visit to confirm the pages load and the domlog starts filling.

Edge cases and variants​

  • Fresh installs: write /etc/wwwacct.conf ADDR and /etc/mainip before creating any account and the wrong-address problem never happens; this applies beyond restores.
  • Not Aliyun-specific: AWS Elastic IPs and similar NAT-style public IPs behave the same. Anywhere the public IP is absent from hostname -I, cPanel's IP settings must use the private address.
  • Local verification blind spot: testing from the server against 127.0.0.1 or the public address hits the default vhost and misleads β€” use the private IP with an explicit Host header.

Warnings

  • The three IP stores are caches of each other, not backups: /etc/wwwacct.conf governs new accounts, /var/cpanel/users/ holds account metadata, userdata drives vhost generation β€” the fix is complete only when all three are rewritten.
  • Back up the userdata directory before bulk sed; socket files like scope must be skipped.
  • Do not convict the default vhost on a 404 alone β€” pair the empty domlog with the error page's origin before concluding.

Frequently Asked Questions​

Why does my cPanel site show the default page after a migration?​

Because the vhost address never matches. On Aliyun ECS the NIC only carries a private IP β€” the public IP lives on an edge NAT gateway. A restore inherits the old server's public IP, Apache matches vhosts by IP:port, no vhost ever matches, and everything falls into the wildcard default vhost. Rewriting three IP stores to the private IP and rebuilding httpd.conf fixes it.

How do I check which Apache vhost is serving my requests?​

Two checks give a verdict: the site's domlog stays completely empty, and a request for a static file that certainly exists returns 404 with an error page styled from the default document root (/var/www/html). Both together mean the default vhost is answering. Then compare httpd -S against hostname -I to see whether the bound address actually exists on the NIC.

Which cPanel IP settings need updating on a NAT cloud server?​

Three places together: ADDR in /etc/wwwacct.conf (global default), IP= in /var/cpanel/users/ account files, and every ip: field under /var/cpanel/userdata/ β€” then run /scripts/rebuildhttpdconf and restart httpd. For new accounts the default comes from /etc/mainip; writing the private IP there before migration prevents the problem from recurring.

CCLEE

Independent developer, 24 years in e-commerce, focused on grounding AI in real business scenarios.

Work with me

cPanel AutoSSL Not Issuing? Self-Signed Certificate Fix

Β· 8 min read

You open your own website hosted on a cPanel server, and the browser warns "Your connection is not private" β€” the certificate details show an issuer that is a temporary hostname generated during the cPanel installation, with no relation to your domain.

Encountered this while migrating a client's two China sites into a compliance hosting environment β€” long-expired certificates and browser security warnings were among the legacy issues we had to clear before sign-off.

TL;DR​

When the browser reports an untrusted self-signed certificate, the CA is usually fine β€” the real Let's Encrypt certificate was never issued. Check two things in order: first the AutoSSL per-account domain exclusion list (whmapi1 get_autossl_user_excluded_domains); once cleared, trigger issuance immediately with start_autossl_check_for_one_user. If issuance succeeds but the public still sees a self-signed certificate, look for a custom vhost pinning SSLCertificateFile. And note that already optimal does not mean full coverage β€” trust only the SAN of the certificate the public actually receives.

Symptoms​

Run a certificate check against the domain from an external machine:

$ openssl s_client -connect example.cn:443 -servername example.cn </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
subject=C = US, O = cPanel, L = Houston, ST = TX, OU = SSL Support, CN = 203-0-113-10.cprapid.com
issuer=C = US, O = cPanel, L = Houston, ST = TX, OU = SSL Support, CN = 203-0-113-10.cprapid.com
notBefore=May 21 00:00:00 2026 GMT
notAfter=Aug 19 00:00:00 2026 GMT

Three signals stack up: issuer identical to subject (self-signed), a CN that is the cprapid temporary hostname cPanel generated at install time (unrelated to the site), and validity dates matching the cPanel service certificate. In other words, visitors receive cPanel's self-signed service certificate β€” the Let's Encrypt certificate never reached the public.

The confusing part: inside WHM, AutoSSL looks perfectly healthy. Provider is Let's Encrypt, the daily task runs on schedule, and no errors appear. The AutoSSL log reveals the real reason:

User-excluded domains: 9 (mail.example.cn, webmail.example.cn, ...)

All 9 domains of the account are on the exclusion list β€” AutoSSL treats that as user intent, skips them every run, and wraps up with "already optimal".

Root causes​

Cause one: the domain exclusion list blocks issuance (primary). AutoSSL maintains a per-account exclusion list; domains on it never enter issuance. It neither errors nor warns β€” the daily task simply runs to completion, which is why the panel looks normal. The list gets populated in three common ways:

  • Manual exclusions early on: the domain had no DNS or was still in testing, and the exclusion was never cleaned up
  • cpmove migrations carry it over: restoring an archive brings the old server's exclusion state and old certificates to the new machine
  • Newly created subdomains: cPanel adds a subdomain (together with its www.* form) to the list by default

Cause two: a custom vhost pins the certificate path. After clearing the list, the log confirmed a successful issuance β€” yet the public still received the self-signed certificate. Issued, but not served. This server carried a custom Apache include (a mirror vhost added for public IP routing) whose SSLCertificateFile was hardcoded to /var/cpanel/ssl/cpanel/cpanel.pem, cPanel's self-signed service certificate. Standard vhosts in cPanel's httpd.conf bind only the main IP, so all public traffic hit the mirror vhost and never saw the AutoSSL result.

The two causes stack: clearing only the list issues a certificate nobody sees; fixing only the vhost points the mirror at a certificate that was never issued. Fix one, then two β€” both are required.

Fix​

1. Locate from outside. Run the certificate check from an external machine (not on the server itself β€” see the warnings at the end). Once issuer equals subject is confirmed, query the exclusion list on the WHM server:

whmapi1 get_autossl_user_excluded_domains username=example

2. Clear the exclusion list. The domain parameter is repeatable, so all domains that need certificates can be allowed in one call:

whmapi1 remove_autossl_user_excluded_domains \
username=example domain=example.cn domain=www.example.cn

Service subdomains such as mail or webmail that have no DNS record or do not need certificates are reasonably kept excluded β€” removing them only fills the log with DCV errors without producing any certificate.

3. Trigger issuance immediately. The daily task waits for the scheduler; a manual run executes now:

whmapi1 start_autossl_check_for_one_user username=example

Two naming details: there is no shorter variant without _for_one_user, and the parameter is username, not user. When unsure about function names, grep the module source:

grep -i autossl /usr/local/cpanel/Whostmgr/API/1/SSL.pm

The CLI equivalent is /usr/local/cpanel/bin/autossl_check --user=example. Logs land in /var/cpanel/logs/autossl/, one directory per timestamp; they contain binary characters, so filter with grep -a or strings before reading.

4. If issuance succeeded but the public still sees the old certificate, inspect custom vhosts. ACME requests succeeded and the certificate is on disk, yet visitors get the old one β€” traffic is not flowing through the standard vhost. Search the custom include for a pinned path:

grep -rn "SSLCertificateFile" /etc/apache2/conf.d/includes/post_virtualhost_global.conf

Replace the hardcoded cpanel.pem with the per-domain certificate path:

SSLCertificateFile /var/cpanel/ssl/apache_tls/example.cn/combined

Then restart with /scripts/restartsrv_httpd. This include file is custom configuration β€” cPanel does not overwrite it when rebuilding httpd.conf, so future renewals take effect automatically. One edit is enough.

5. Final verification. Re-run the step 1 command from outside: the issuer should now be a Let's Encrypt intermediate (R3/R10/R11 depending on LE rotation) and the SAN should include the site domain. Let's Encrypt certificates last 90 days; AutoSSL's daily task renews them from here on without further action.

Migration and subdomain variants​

  • After a cpmove migration: the exclusion list and old certificate state arrive intact, and the old LE certificate's SAN usually covers only the apex and www. After a restore, clean the exclusion list and trigger issuance once β€” do not wait for the daily task.
  • Newly created subdomains: cPanel auto-excludes them together with www.test.; remove the exclusion after creation. A www.test. without DNS resolution is better left excluded to avoid recurring DCV errors.
  • Domains attached via ServerAlias: aliases injected through userdata includes are not managed by AutoSSL, and hand-editing parked_domains in userdata plus updateuserdomains gets silently dropped. The supported path is the official API:
uapi --user=example SubDomain addsubdomain domain=test rootdomain=example.cn dir=/home/example/public_html

Note the parameter is rootdomain β€” passing parentdomain is silently ignored and the API replies "You must specify a main domain".

Warnings

  • Do not verify certificates from the server itself using 127.0.0.1 or the main IP β€” you will hit the default vhost and misread the result. Trust only external openssl s_client output.
  • whmapi1 outputs YAML by default; add --output=json before piping to jq.
  • "already optimal" in the panel only means no issuance is due for the account β€” it does not prove coverage. Check the actual certificate SAN.

Frequently Asked Questions​

Why is cPanel AutoSSL not issuing certificates?​

Check the certificate itself: if the issuer equals the subject and the CN is a cPanel temporary hostname, no real certificate was ever issued. The two most common causes are the per-account AutoSSL domain exclusion list, and a custom vhost pinning SSLCertificateFile to the cPanel self-signed service certificate. Let's Encrypt certificates are valid for 90 days; once issuance succeeds, AutoSSL's daily task renews automatically.

What are cPanel AutoSSL user excluded domains?​

A per-account list of domains that AutoSSL deliberately skips. Beyond manual exclusions, a cpmove restore carries the old server's list over, and newly created subdomains are auto-excluded (including www.test.*) β€” in our case all 9 domains of one account were on the list. Remove them with whmapi1 remove_autossl_user_excluded_domains, then trigger start_autossl_check_for_one_user instead of waiting for the daily run.

Why is cPanel AutoSSL not renewing certificates?​

"already optimal" in the AutoSSL panel only means no renewal is due β€” it does not confirm coverage. Domains on the exclusion list are skipped silently, so nothing is ever issued or renewed, and Let's Encrypt certificates expire after 90 days. Verify the live SAN with openssl s_client from an external machine, clean the exclusion list, and trigger issuance manually; the daily task takes over renewal afterwards.

CCLEE

Independent developer, 24 years in e-commerce, focused on grounding AI in real business scenarios.

Work with me

cPanel Install Says Complete but MariaDB Is Missing

Β· 7 min read

You provision a fresh server with cPanel, the installer reports "complete" β€” and then account creation, database setup, or the sites themselves fail one after another. These failures share a trait: the place that errors is not the place that broke.

Encountered this while building a compliance hosting environment on Aliyun China for a client β€” all three failure classes showed up on the same machine during provisioning, and each had to be cleared before the site migration could start.

TL;DR​

Fresh cPanel installs fail in three recurring ways, all wearing a mask of success: the installer reports complete while MariaDB never installed (a failed stage does not roll back); account creation is blocked by a chain of missing keys when /etc/wwwacct.conf is empty; and from China, httpupdate.cpanel.net crawls at roughly 50 KB/s β€” slow enough to cause the first failure in the first place. Accept a provisioning only after three checks: MariaDB RPMs present, mysql service active, client connects.

Scenario one: install reports complete, MariaDB is missing​

WordPress throws a Database Error, the mysql binary does not exist on the server, and systemctl is-active mysql returns inactive β€” while the cPanel installer reported success and the panel opens fine.

The install log's tail hides the real event:

(FATAL): The background process "SQL Databases and dependent apps" failed ... error number 127

The MariaDB RPM transaction in the SQL stage failed on download, but every later stage ran and finished anyway, and the final screen still said complete. Installation "success" does not mean the components are present β€” the installer neither rolls back nor blocks on a stage failure.

Fix order:

  1. Confirm the gap: rpm -q MariaDB-server β€” most likely not installed
  2. Install the full RPM set: MariaDB-server, MariaDB-client, MariaDB-devel, MariaDB-shared, MariaDB-common β€” every one of them
  3. RPMs alone are not enough β€” /usr/local/cpanel/scripts/securemysql does not make restore tools connect; restorepkg fails with Missing: admin_mysql_password. Create /root/.my.cnf with a client-section password and run SET PASSWORD for root@localhost

Never trust the installer's exit status for acceptance. Run three checks:

rpm -qa | grep -i maria
systemctl is-active mysql
mysql -N -e "select version()"

All three green, the SQL stage is genuinely done.

Scenario two: first account creation hits a chain of missing keys​

restorepkg or manual account creation gets blocked once per run, in this order: Please setup a nameserver β†’ Missing HOMEDIR β†’ Missing DEFMOD β†’ Missing LOGSTYLE β†’ Missing SCRIPTALIAS.

The cause is direct: on a fresh WHM that never ran the Basic Setup wizard, /etc/wwwacct.conf is an empty file, and account creation validates it hard. The trap is the error mechanism β€” each run reports exactly one missing key, so patching one at a time costs five or more rounds.

Write the full standard key set in one shot:

cat > /etc/wwwacct.conf <<'EOF'
ADDR 172.28.100.10
CLUSTERED_DNS disabled
DEFMOD default
ETHDEV eth0
FTPHOMEDIR 0
HOMEDIR /home
HOMEMATCH home
LANG english
LOGSTYLE semicolon
MINUID 500
NS ns1.example-ns.com
NS2 ns2.example-ns.com
SCRIPT x3
SCRIPT x3parked
SCRIPT x3addon
SCRIPTALIAS y
EOF

Three details:

  • ADDR takes the private IP, not the public one β€” on NAT architectures the public IP never lands on the NIC, and the consequences of binding it are covered in cPanel Sites Hit the Default Page? The Aliyun NAT vhost Trap
  • whmapi1 set_nameserver takes the singular parameter nameserver (values: bind/powerdns/disabled), unlike the plural fields from get_nameserver_config; and the NS validation reads NS/NS2 from wwwacct.conf, not ns1/ns2 from cpanel.config
  • When real DNS lives on cloud DNS, the NS values are nominal placeholders β€” pair with CLUSTERED_DNS disabled

For failed transfers, the details live in the JSON of /var/cpanel/transfer_sessions/<session>/master.log (search failure); note that view_transfer itself tails and blocks β€” do not get stuck in it during triage.

Scenario three: cpanel.net downloads at 50 KB/s from China​

Scenario one's RPM download failure usually traces back here: from an Aliyun Shanghai ECS, every mirror IP of httpupdate.cpanel.net measured about 50 KB/s (the international-site route in the same region was just as slow, ruling out any proxy transit benefit); the same source over a residential connection measured 1.8-6 MB/s.

The acceleration pattern lets the server borrow a faster line: a reverse dynamic SOCKS tunnel from a local machine, with proxychains-ng wrapping the installer on the server:

# Local machine: open a remote dynamic SOCKS port
ssh -N -R 1080 root@<server-ip>

# Server: with proxychains-ng installed, run the installer through the tunnel
proxychains4 -q sh latest

Measured lift: from 50 KB/s to 708 KB/s, about 14x. Three traps to avoid:

  • The proxychains config must exempt localnet ranges (10/8, 172.16/12, 100.64/10, etc.) and drop proxy_dns β€” otherwise Aliyun internal mirror domains (mirrors.cloud.aliyuncs.com) get pushed into the tunnel and fail outright
  • tinyproxy is incompatible with httpupdate.cpanel.net β€” it returns 404 reliably; do not use it as the tunnel exit
  • Never clean up the installer with pkill -f "sh latest" β€” the pattern matches your own ssh session's command line and kills your connection (the source of exit code 255); kill by PID instead

Tear it down when done: the tunnel lives exactly as long as the local ssh process, and the server keeps no proxy configuration β€” uninstall proxychains-ng and delete its config after the install. If an interrupted install already left RPMs missing, cPanel's self-repair is /usr/local/cpanel/scripts/sysup β€” in our case a missing splitlogs binary had left httpd unable to start, fixed by sysup plus a manual RPM install.

Warnings

  • The three failure classes chain together: slow downloads break RPM transactions, the installer skips rollback and reports success, and the missing components explode later at account creation or site setup. Debug from the network layer up β€” do not stop at the layer that surfaced the error.
  • wwwacct.conf reports one missing key per run; writing half the file and retesting only burns rounds. Write it complete.
  • Tunnel acceleration is a temporary tool β€” no resident proxy configuration stays on the server; after the RPMs land, run sysup once for a full reconciliation.

Frequently Asked Questions​

How do I install MariaDB on a cPanel server?​

Install the full RPM set β€” MariaDB-server, MariaDB-client, MariaDB-devel, MariaDB-shared and MariaDB-common; a partial set passes rpm checks but breaks later steps. Then create /root/.my.cnf with a client-section password and run SET PASSWORD for root@localhost, otherwise restore tools fail with Missing: admin_mysql_password. Verify with rpm -qa | grep -i maria, systemctl is-active mysql, and mysql -N -e "select version()".

Why does a cPanel install or update fail without an error?​

Because the installer does not roll back. When one background stage fails (SQL Databases and dependent apps, error number 127 in our case), the remaining stages still run and the installer still reports success β€” the only trace is a (FATAL) line at the tail of the install log. Always grep the log tail for FATAL and run the three-component acceptance checks before trusting the completion message.

How can I speed up cPanel downloads in China?​

Direct throughput from a China cloud server to httpupdate.cpanel.net measures around 50 KB/s across all mirror IPs, while the same source reaches 1.8-6 MB/s over a residential line elsewhere. The workable pattern is a reverse dynamic SOCKS tunnel from a faster network plus proxychains on the installer β€” measured 14x faster at about 708 KB/s. Treat it as temporary: uninstall the proxy tooling when the install finishes.

CCLEE

Independent developer, 24 years in e-commerce, focused on grounding AI in real business scenarios.

Work with me