# cPanel restorepkg and pkgacct: Backup and Restore from CLI

Source: https://srvscripts.com/guides/cpanel-restorepkg-pkgacct-cli/
Updated: 2026-10-06
Publisher: srvScripts (https://srvscripts.com/)

**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.

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:

| Option | What it does | When to use it |
| --- | --- | --- |
| --skiphomedir | Leaves out the home directory | You copy files separately with rsync. Our test archive went from 71 MB to 32 KB. |
| --skipacctdb / --skipmysql | Leaves out all databases / only MySQL content | Databases are moved another way |
| --skiplogs, --skipbwdata | Leaves out access logs / bandwidth data | Smaller, faster archives for migrations |
| --dbbackup=(all|schema|name) | Full databases, structure only, or names only | schema is handy for testing a restore quickly |
| --mysql=X.X | Sets the minimum MySQL version that should be able to restore the backup | Destination runs an older MySQL/MariaDB |
| --split | Creates the file in chunks | Very large accounts, size-limited transfer targets |
| --incremental | Refreshes an existing package (uncompressed) | Repeated syncs before a cutover |
| --nocompress / --compress | Uncompressed tar / gzip | Trade CPU against disk and transfer size |
| --stdout-archive | Writes the archive to standard output, no other output | Streaming straight to another host |
| --serialized_output | JSON-encoded output | Scripts 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`:

| Option | Effect |
| --- | --- |
| --newuser alice | Restore under a different username. Databases and DB users keep their names unless there is a conflict. |
| --ip=y / --ip=n / --ip=203.0.113.20 | Assign a dedicated IP (random free one, none, or a specific address) |
| --skipaccount | Restore into the existing account with the same username |
| --force | Restore and overwrite all account settings and databases. On an existing account it implies –skipaccount. |
| --update_dns_zone=0 | Restore everything except the DNS zones, so you decide when the site goes live here |
| --allow_reseller | Restore reseller privileges if the archive has them (unrestricted mode only) |
| --restricted | Restricted Restore: extra security checks on the archive. cPanel calls it experimental. |
| --shared_mysql_server | Skip some grants and databases that already exist on a shared database server |
| --from-stdin | Read 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](/scripts/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](/guides/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](/scripts/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](https://docs.cpanel.net/whm/scripts/the-pkgacct-script/) · [cPanel docs: the restorepkg script](https://docs.cpanel.net/whm/scripts/the-restorepkg-script/) · [cPanel docs: Backup Restoration](https://docs.cpanel.net/whm/backup/backup-restoration/)

**Related:** [Transferring accounts between servers with the WHM Transfer Tool](/guides/whm-transfer-tool/) · [Migrate cPanel accounts to a new server without customers noticing](/guides/migrate-cpanel-accounts-new-server/) · [WHM Backups S3: Reliable Remote Backups and Test Restores](/guides/whm-backups-s3-test-restore/) · [cPanel Migration Preflight Check](/scripts/cpanel-migration-preflight/) · [Backup Verify Script](/scripts/backup-verify/)

**See also:** [JetBackup 5 Restore in WHM: Accounts, Files, Databases, Email](/guides/jetbackup-5-restore-admin/) · [JetBackup 4 to 5 Migration: The 5.2.11 Stepping Stone](/guides/jetbackup-4-to-5-migration/) · [Restic Backup for cPanel and DirectAdmin: Files, Databases, Retention](/guides/restic-backup-cpanel-directadmin/)

## 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.
