Emergency server help: get in touch

cPanel restorepkg and pkgacct: Backup and Restore from CLI

Back up and restore cPanel accounts from the shell with /scripts/pkgacct and /scripts/restorepkg: options, file locations, moving to a new server and common errors.

Published 8 min read

Short answer: /scripts/pkgacct bob /backup packs the cPanel account bob into /backup/cpmove-bob.tar.gz, with files, databases, mail, DNS and settings. Without a target directory the archive goes in /home. Copy it to the other server and run /scripts/restorepkg /home/cpmove-bob.tar.gz. Add --newuser to restore under another username, --ip=y for a dedicated IP, and --force only when you really mean to overwrite an existing account. Restore archives only from sources you would trust with root.

Applies to cPanel & WHM 11.138, AlmaLinux 9.8, MariaDB 10.11

We ran /scripts/pkgacct (normal, --skiphomedir --skiplogs and --stdout-archive) and the --help output of both scripts on our lab server (AlmaLinux 9.8, cPanel & WHM 11.138, MariaDB 10.11) on 6 October 2026, then deleted the test archives. We did not run restorepkg, because it would create or overwrite accounts on the lab. Its options come from the lab’s --help output and cPanel’s documentation.

Create a full account backup with pkgacct

/scripts/pkgacct bob                    # writes /home/cpmove-bob.tar.gz
/scripts/pkgacct bob /backup/migration  # writes /backup/migration/cpmove-bob.tar.gz

The syntax from the lab’s help output is pkgacct [options] user [workdir]. If you pass options, put them before the username. pkgacct first builds a working directory (cpmove-bob/) next to the archive and then compresses it, so the target filesystem needs room for the account plus the archive. Here is the end of a real run for our test account site1 (WordPress, 150 MB home directory, one database), with the target directory shortened to /backup/test:

[2026-10-06 00:01:29 -0500] pkgacct working dir : /backup/test/cpmove-site1
...
[2026-10-06 00:01:30 -0500] Storing database site1_wp
...
[2026-10-06 00:01:44 -0500] pkgacctfile is: /backup/test/cpmove-site1.tar.gz
[2026-10-06 00:01:44 -0500] md5sum is: 4cfe57ad1abcba99256bd5023d0dd024
[2026-10-06 00:01:44 -0500] size is: 70863009
[2026-10-06 00:01:44 -0500] homesize is: 157683712
[2026-10-06 00:01:44 -0500] homefiles is: 4474
[2026-10-06 00:01:44 -0500] mysqlsize is: 835584
[2026-10-06 00:01:44 -0500] pkgacct completed

It took 16 seconds and produced a 71 MB archive with mode 600 (root only). Write down the md5sum line, because you will use it to check the copy on the other server. Inside the archive, the top-level cpmove-site1/ folder holds, among others, homedir/, mysql/ and mysql.sql (databases and grants), dnszones/, userdata/, ssl/, domainkeys/, cron/ and cp/ (the cPanel user file).

Useful pkgacct options

All of these appear in /scripts/pkgacct --help on cPanel 11.138:

OptionWhat it doesWhen to use it
--skiphomedirLeaves out the home directoryYou copy files separately with rsync. Our test archive went from 71 MB to 32 KB.
--skipacctdb / --skipmysqlLeaves out all databases / only MySQL contentDatabases are moved another way
--skiplogs, --skipbwdataLeaves out access logs / bandwidth dataSmaller, faster archives for migrations
--dbbackup=(all|schema|name)Full databases, structure only, or names onlyschema is handy for testing a restore quickly
--mysql=X.XSets the minimum MySQL version that should be able to restore the backupDestination runs an older MySQL/MariaDB
--splitCreates the file in chunksVery large accounts, size-limited transfer targets
--incrementalRefreshes an existing package (uncompressed)Repeated syncs before a cutover
--nocompress / --compressUncompressed tar / gzipTrade CPU against disk and transfer size
--stdout-archiveWrites the archive to standard output, no other outputStreaming straight to another host
--serialized_outputJSON-encoded outputScripts and automation

With --stdout-archive you choose where the bytes go. On the lab, /scripts/pkgacct --stdout-archive site1 > file.tar.gz produced a valid archive in 11 seconds. But the redirected file was created with mode 644 (world-readable), unlike pkgacct’s own mode-600 file. Archives contain password hashes and database dumps, so set umask 077 first or chmod 600 straight after.

Copy the archive to the new server

# on the old server
rsync -avP /home/cpmove-bob.tar.gz root@203.0.113.10:/home/

# on the new server: compare with the md5sum line printed by pkgacct
md5sum /home/cpmove-bob.tar.gz
chmod 600 /home/cpmove-bob.tar.gz

Use the backup network or a private link if you have one, and delete the archive from both servers when the migration is done.

Restore with restorepkg

/scripts/restorepkg is a link to /usr/local/cpanel/bin/restorepkg. Give it either a path or just a username:

/scripts/restorepkg /home/cpmove-bob.tar.gz     # explicit file (clearest)
/scripts/restorepkg bob                          # search the standard locations for bob's archive

With only a username, cPanel’s documentation says restorepkg searches /home, /home2, /home3, /root, /usr, /usr/home and /web. It accepts names such as cpmove-bob.tar.gz, bob.tar.gz and the dated backup-...bob.tar.gz files made by WHM backups, plus uncompressed and already-extracted variants. Pass the full path to avoid restoring an older archive by accident.

Options you will actually use, from the lab’s restorepkg --help:

OptionEffect
--newuser aliceRestore under a different username. Databases and DB users keep their names unless there is a conflict.
--ip=y / --ip=n / --ip=203.0.113.20Assign a dedicated IP (random free one, none, or a specific address)
--skipaccountRestore into the existing account with the same username
--forceRestore and overwrite all account settings and databases. On an existing account it implies –skipaccount.
--update_dns_zone=0Restore everything except the DNS zones, so you decide when the site goes live here
--allow_resellerRestore reseller privileges if the archive has them (unrestricted mode only)
--restrictedRestricted Restore: extra security checks on the archive. cPanel calls it experimental.
--shared_mysql_serverSkip some grants and databases that already exist on a shared database server
--from-stdinRead the archive from standard input (requires –newuser)

Overwriting a live account with --force or --skipaccount replaces its files, mail and databases with the archive’s version. Before you do it, make a fresh backup of the current account (/scripts/pkgacct bob /root/pre-restore) and check the archive date. Do not combine --newuser with --skipaccount unless you understand that it can overwrite a different existing user. The help text warns about exactly this.

The help text also has a security note that is worth repeating: do not restore account backups in unrestricted mode (the default) from anyone you would not trust with root access to the server. A crafted archive can add or escalate privileges. Restricted Restore adds checks, but cPanel says it should not be treated as a security control yet.

Restoring on a new server: checklist

  • cPanel version: restore onto the same or a newer cPanel version.
  • Database version: the destination should run the same or a newer MySQL/MariaDB. For an older destination, create the archive with --mysql=X.X.
  • PHP versions: install the EA-PHP versions the account uses before the restore, or its sites fall back to the server default. Our cPanel PHP Version Audit script lists them on the old server.
  • IP addresses: decide on shared vs dedicated before the restore (--ip).
  • DNS: use --update_dns_zone=0 if DNS is hosted elsewhere or you want a staged cutover.
  • Two-factor authentication: per cPanel’s documentation, 2FA settings do not transfer. Users must set it up again.

For many accounts at once, the WHM Transfer Tool is usually better: it runs pkgacct and restorepkg for you and can copy straight from the old server (see WHM Transfer Tool). Use the CLI when the source is not reachable, when you only have an archive, or for one account. Run our cPanel Migration Preflight check on both servers first.

Check that the restore worked

whmapi1 accountsummary user=bob | grep -E "domain|diskused|suspended"
uapi --user=bob Mysql list_databases | grep database:
ls -la /home/bob/public_html | head

Then test the site before DNS points to the new server: add the domain to your local hosts file with the new IP. Log in to webmail, open the main pages and the admin area, and check that SSL was reissued or restored.

Common problems

  • pkgacct fails partway or produces a tiny archive: the target filesystem ran out of space. pkgacct needs room for the working directory and the archive. Check with df -h and use another target directory.
  • restorepkg stops because the account or a domain already exists: the username or one of its domains is already on the destination. Remove the old copy first (after backing it up), restore with --newuser, or use --force when you intend to overwrite.
  • Sites show the wrong PHP version after restore: that EA-PHP version is not installed on the destination. Install it and set the domain’s version in MultiPHP Manager.
  • Databases missing: the archive was made with --skipacctdb/--skipmysql or --dbbackup=schema, or a database name conflicted on a shared database server.
  • Restoring JetBackup 4 backups: JetBackup’s own migration guide says JB4 backups can still be restored manually with restorepkg after you move to JetBackup 5.

Official documentation: cPanel docs: the pkgacct script · cPanel docs: the restorepkg script · cPanel docs: Backup Restoration

Related: Transferring accounts between servers with the WHM Transfer Tool · Migrate cPanel accounts to a new server without customers noticing · WHM Backups S3: Reliable Remote Backups and Test Restores · cPanel Migration Preflight Check · Backup Verify Script

See also: JetBackup 5 Restore in WHM: Accounts, Files, Databases, Email · JetBackup 4 to 5 Migration: The 5.2.11 Stepping Stone · Restic Backup for cPanel and DirectAdmin: Files, Databases, Retention

Frequently asked questions

Where does pkgacct save the backup?

In /home by default, as cpmove-USERNAME.tar.gz. Add a directory after the username to save it elsewhere, for example /scripts/pkgacct bob /backup.

How do I restore a cpmove file on a new cPanel server?

Copy it to the new server, check the md5sum, and run /scripts/restorepkg /home/cpmove-bob.tar.gz. Make sure the PHP and database versions on the new server are the same or newer.

Can I restore a cPanel backup under a different username?

Yes, with /scripts/restorepkg –newuser alice /home/cpmove-bob.tar.gz. Databases keep their names unless there is a conflict.

How do I make a cPanel backup without the home directory?

Run /scripts/pkgacct –skiphomedir bob /backup. Options go before the username. Copy the files separately, for example with rsync.

Is it safe to restore a backup a customer uploaded?

Only if you would trust them with root. cPanel warns that unrestricted restores of untrusted archives can escalate privileges. Restricted Restore adds checks but is still described as experimental.

Maintenance record

This guide changes servers, data or security settings, so we re-check it against current versions on a fixed schedule. Take a backup or snapshot before you start.

Maintained by
srvScripts editorial team
Supported versions
Tested on cPanel & WHM 11.138, AlmaLinux 9.8, MariaDB 10.11
Last full review
Next review

Free website test

Is your website set up right?

Check SSL, security headers, redirects, robots.txt, sitemap, llms.txt and security.txt in one test. It takes about 30 seconds.