Appearance
Troubleshooting
Messages are quoted as they appear in the panel or the log, so you can search this page.
Start here for almost anything:
sh
php artisan offsite-backups:status # worker, queue and destination health
php artisan offsite-backups:status --json # the same, for scriptsThe worker
Copies stay queued and nothing happens
The transfer worker is not running. Backups are only copied by offsite-backups:work.
sh
php artisan offsite-backups:statusWorker ................ offline - run php artisan offsite-backups:workStart it and keep it alive with supervisor, systemd or a second Docker container. The admin Overview turns green once it is beating.
The worker dies after a few minutes
| Cause | Fix |
|---|---|
Allowed memory size exhausted | The worker restarts at 512 MB by default and streaming should stay flat. If it does not, raise the memory limit and report it. |
| Killed by the OOM killer | A transfer is buffering. Check the temp directory has space. |
| Container restart loop | The container is missing the panel's env file or volumes — it needs the same ones as the panel. |
Connection refused to the database | The worker cannot reach the database. Use the same network as the panel. |
"Worker: panel queue worker"
That is a warning while Queue mode is dedicated. Check Settings → Queue worker: if it is set to Panel queue worker, transfers share the panel's queue and long ones get cut short. Switch to Dedicated.
"N copies look stuck (no heartbeat for 5 minutes)"
The worker was killed mid-transfer. Requeue them:
sh
php artisan offsite-backups:recoverPartial uploads are abandoned rather than resumed, so the copy restarts from the beginning. Safe to run repeatedly.
Destinations and connections
Test connection fails at resolve
The endpoint points at a private address, or at localhost. That is the SSRF guard doing its job.
- Public provider (S3, R2, B2, Wasabi, Hetzner): the endpoint is wrong. Use the public endpoint from Storage providers.
- Your own storage on the LAN: tick Allow private network addresses on that destination, and only for storage you control.
Test connection fails at write, read or delete
| Message contains | Cause | Fix |
|---|---|---|
Access Denied, 403 | The key lacks permission, or the bucket is wrong | The key needs put, get, delete and list permission on that bucket |
NoSuchBucket | Wrong bucket name or region | Check the bucket exists in that region |
SignatureDoesNotMatch | Wrong secret, or wrong region | Re-copy the secret; watch for trailing spaces |
InvalidAccessKeyId | Wrong key, or a key from another account | — |
Connection timed out, Could not resolve host | Firewall, DNS or wrong port | Check from the panel host |
SSL certificate problem | Self-signed certificate on your own storage | Install a valid certificate; do not disable verification |
SFTP: "The host key is not pinned yet"
Pinning is deliberate — it prevents a man-in-the-middle. Click Pin this host key on the destination after a successful test, then save. If the host was reinstalled, its key changed and you must pin the new one.
SFTP: "Authentication failed"
Use key-based authentication where possible. If you use a password, check for characters that need quoting. The user needs write access to the configured path.
SFTP: "The server did not present a host key"
The server is not offering an SSH host key, usually a non-OpenSSH service or a proxy. Fix the SFTP server; there is no safe way to skip this.
"The destination prefix contains invalid characters"
The prefix must be a relative path: letters, digits, -, _, . and /. No .., no leading slash and no spaces.
Backups and copies
A backup shows Local only and never changes
The copy was never queued. Check, in order:
- A backup rule matches that server (Backup rules → Which servers).
- Off-site is on for that server.
- The server's allowance is not full.
"The panel backup was deleted before it could be copied"
The local backup was removed while the upload was still queued. If it repeats, retention is deleting local backups before copies finish — raise the local retention, or lower concurrency.
"Checksum mismatch"
The bytes that arrived do not match what the node recorded. Possible causes:
- A proxy or CDN rewriting the body
- A disk error on the node or the storage
- The backup was modified after it was created
The copy is not marked verified and will retry. If it fails every time, download the backup manually and compare the checksum.
"Could not reach node" or "The node refused the restore"
The panel cannot exchange the archive with the node. Usually the panel URL the nodes are told to use is wrong or unreachable.
- Settings → Panel URL for nodes must be an address your nodes can reach — normally your public panel URL, not
localhostor a Docker-internal name. - Test from the node that it can reach the panel.
- If the panel is behind Cloudflare, allow the node's address through, or use a direct hostname.
"The backup archive no longer exists on node"
A copy was queued, then the local backup was deleted before the upload started. Turn on Delete the node copy only after the off-site copy is verified, or raise the local retention.
"The copied object cannot be found"
The storage said the upload finished, but the object is not there. Almost always a prefix that changed after the upload started, or a lifecycle rule that deleted the object immediately. Check the bucket's lifecycle policy.
"The object read back does not match what was written"
Verification read back different bytes. Either the storage is corrupting data, or something is intercepting traffic. Re-run Test connection; if the read-back step fails there too, the destination is the problem, not the backup.
"Writing the upload part to the temporary buffer failed"
Uploads buffer each part in the panel's storage. Free some space, or lower Settings → Upload part size.
A copy failed five times and stopped
Fix the cause, then:
sh
php artisan offsite-backups:retry --failedTo retry one copy, pass its identifier with --copy=.
Uploads are slow, or saturate the link
Set Settings → Bandwidth limit, or an upload window such as 01:00–06:00. Lower Concurrency per destination too.
Restore and download
| Message | Meaning | Fix |
|---|---|---|
| "Only completed off-site copies can be restored" | The copy is still uploading, failed, or was pruned | Wait, or retry it |
| "A restore is already running for this server" | One restore per server at a time | Wait for it to finish |
| "The server is not in a state that allows a restore right now" | The server is installing, transferring or suspended | Finish that first |
| "The server is being transferred to another node" | A move is in progress | Restore after it completes |
| "Requesting node does not have permission" | The server moved while the restore was queued | Retry |
| Download link says 403 or expired | Links are single-use and expire | Reload the page and download again |
If a restore finishes but the server will not start, check the server console. If Delete all files first was off, old files may remain and conflict — restore again with it on.
Encryption
| Message | Meaning | Fix |
|---|---|---|
| "Encryption key cannot be read; was APP_KEY changed?" | The key is stored encrypted with the panel's APP_KEY | Restore the old APP_KEY, or decrypt outside the panel with the recovery kit |
| "Encryption key is not in this panel" | Wrong recovery kit, or a copy from another panel | Use the kit the key was exported to |
| "Decryption failed: the file was modified or the key is wrong" | Exactly what it says | Check the kit and re-download the file |
| "The encrypted file is truncated" | The download is incomplete | Download it again |
Decrypting outside the panel only needs PHP 8.3+, the recovery kit and the decryption tool that ships with the extension.
Panel and interface
The Offsite Backups menu item is missing
sh
php artisan optimize:clear
php artisan p:extension:listIf it is listed but disabled, enable it, then hard-reload the browser. Check the panel log for a storage-provider error.
The page loads but every value is empty
The interface assets were not published. Reinstall the extension, or publish them again, then hard-reload.
Customers see no off-site information
Check, in order:
- A backup rule matches their server.
- Off-site backups are on for that server.
- Their subuser role has the Offsite Backups permissions.
- Settings → Show the customer banner is on, for the banner only.
Orphans and deleted servers
An orphan is an object in your bucket that no server claims — from a manual upload, a changed prefix, or a deleted server. The page shows its size, age and key.
- Restore rebuilds a backup record from the object and attaches it to a server.
- Delete removes the object from storage. That is permanent.
By default, copies of a deleted server are kept for 14 days so they can be restored into another server. Settings → When a server is deleted controls it.
Notifications
- No Discord alert — paste the webhook URL into Settings → Discord webhook and send a test. A 404 means the webhook was deleted. Webhooks to private addresses are blocked unless allowed.
- No email alerts — the panel must have working mail. Test it from the panel.
- No daily summary — turn it on in Settings, make sure the scheduler runs, and send one now with
offsite-backups:summary --force.
Getting help
Include:
- the exact message, and the copy identifier if there is one
- your panel version and
php -v - the output of
php artisan offsite-backups:status --json - the relevant few lines from the panel log
Never send storage keys, bucket secrets, recovery kits or your .env.