---
title: Data Import Tools
description: "RackHelm has four importers, grouped under **Import Data** in the sidebar. The largest is the ClientExec importer, which reads an existing ClientExec installation's database directly and rebuilds its catalogue, clients, services, invoices and tickets inside RackHelm. This article covers that…"
url: "https://rackhelm.com/documentation/data-import-tools/"
updated: "2026-09-24"
category: System Administration
---

# Data Import Tools

RackHelm has four importers, grouped under **Import Data** in the sidebar. The largest is the ClientExec importer, which reads an existing ClientExec installation's database directly and rebuilds its catalogue, clients, services, invoices and tickets inside RackHelm. This article covers that in detail and points you at the other three.

## Before you start

> **Warning:** Import into a fresh install, and take a database backup first. The importer writes directly into your live catalogue, users, orders, invoices and tickets. There is no undo.

> **Note:** The ClientExec importer and the Registrar Domains importer sit behind `edit_company_settings`; the TLD and Enhance importers sit behind `edit_integrations`. The sidebar links are wrapped in `manage_settings` and `manage_integrations` checks — neither key exists in RackHelm's permission list — so in a default install only a Super Admin sees the **Import Data** menu at all.

## The ClientExec importer

Open **Import Data → ClientExec Data Import** (`/admin/import/clientexec`). You need read access to the ClientExec MySQL database — host, port, database name, username and password.

![The ClientExec import screen with database connection fields and per-entity sync modes](/wp-content/uploads/rackhelm-docs/system-import-clientexec.png)
Connection details on the left, four entity toggles with their sync modes, and a live log panel below.

### Connection

| Field | Notes |
| --- | --- |
| **Database Host** | Required. Pre-filled with `127.0.0.1` — but see the warning below. |
| **Database Port** | Required, 1–65535. Defaults to 3306. |
| **Database Name** | Required. |
| **Database Username** | Required. A read-only account is sufficient. |
| **Database Password** | Required. |

> **Warning:** By default the importer refuses private and reserved addresses, including `127.0.0.1` and anything on your LAN — the host is resolved and pinned to a public IP before connecting, to stop the form being used to probe internal services. To import from a local or internal database, set `IMPORT_CLIENTEXEC_ALLOW_PRIVATE=true` in `.env` first. Without it you get the same generic "Could not connect to the specified database" message as a genuine connection failure.

### Import options and sync modes

Four entity groups can be imported independently: **Users**, **Packages**, **Invoices** and **Tickets**. Each has its own mode:

| Mode | Behaviour |
| --- | --- |
| **Try Update Before Insert** | Updates an existing record where one matches, otherwise creates it. The default and the right choice for a re-run. |
| **Only Insert (Skip existing)** | Creates new records and leaves anything already present untouched. |
| **Only Update (Skip new)** | Refreshes records that already exist and creates nothing. |

### What runs, and in what order

The import runs in five passes with real dependencies between them:

1. **Packages and dependencies** — billing cycles, product groups, addons, products, addon prices and package variables.
2. **Users** — custom field definitions, then the user accounts. Imported clients are given your default client role.
3. **Orders and services** — requires both Users *and* Packages; skipped otherwise.
4. **Invoices and items** — requires Users. Once imported, a PDF regeneration job is queued for every invoice.
5. **Support tickets** — requires Users. Departments, tickets, messages and attachments.

A summary of counts is printed at the end. Tables that do not exist in the source database are skipped with a warning rather than failing the run.

### Running it

1. Fill in the connection details and choose your entities and modes.
2. Start the import. RackHelm tests the connection first and refuses to start if it fails.
3. The import runs in the background; the log panel on the page polls for progress. You can navigate away — it keeps running.

The full log is written to `storage/logs/import_clientexec.log` and is reset at the start of each run. Credentials are held in the cache for five minutes under a single-use key and cleared as soon as the background process picks them up.

> **Tip:** Do a first pass with **Packages** only and check the catalogue looks right before importing users, orders and invoices on top of it. Everything downstream inherits whatever the products pass produced.

## Registrar Domains Importer

**Import Data → Registrar Domains Importer** (`/admin/import/domains`) brings domains you already hold at a registrar into RackHelm as billable services. Choose the registrar — eNom, NameSilo, Nominet, OpenSRS, Realtime Register or Namecheap — tick the domains, pick the customer to assign them to, and import.

Points worth knowing:

- The list comes from a local cache of registrar domains, populated by the `domains:sync-providers` console command. If the list is empty, run that first.
- Domains already present in the portal are filtered out, so re-running is safe.
- Each imported domain becomes an active order on an annual billing cycle, with the order item already marked provisioned and its expiry taken from the registrar.
- The price is taken from the matching TLD product's annual renewal price. RackHelm prefers a product wired to that same registrar and falls back to any product named after the TLD; if there is no match at all, the item is imported at zero.

> **Tip:** Import your TLD pricing first with the TLD Importer, so domains land with the right renewal price instead of zero.

## The other two importers

| Importer | What it does |
| --- | --- |
| **TLD Importer** (`/admin/panels/import/prices`) | Pulls a registrar's TLD price list and creates or updates the matching domain products and their billing-cycle prices. |
| **Enhance Importer** (`/admin/panels/import/enhance`) | Reads an Enhance control-panel installation and imports its existing websites and customers as RackHelm services. |

Both live with the integrations screens because each needs a configured integration to talk to.

## Troubleshooting

| Symptom | Cause and fix |
| --- | --- |
| "Could not connect to the specified database" with details you know are correct | Almost always the private-address block. Set `IMPORT_CLIENTEXEC_ALLOW_PRIVATE=true` and retry. The message is deliberately identical for every failure reason, so it never reveals what the server can reach. |
| "Connection credentials expired or invalid" | The cached credentials live for five minutes. Start the import again. |
| Orders were skipped | Pass 3 needs both Users and Packages enabled in the same run. |
| Invoices imported but PDFs are missing | PDF regeneration is queued. Check your queue workers — see [Maintenance, Logs and Health](/docs/maintenance-and-health/). |
| "Skipping table … it does not exist in the source database" | Normal for older ClientExec schemas. That entity is simply not present to import. |
| The log panel stops updating | Read `storage/logs/import_clientexec.log` directly on the server; the panel only mirrors that file. |
| The domain list is empty | The provider cache has not been populated. Run `php artisan domains:sync-providers`, and check the registrar integration is configured. |
| Imported domains show a price of £0.00 | No product matched the TLD. Create or import the TLD product with an annual price, then re-import. |
