Why should I use UXP Backup/Restore over Velero for a Crossplane control plane?
Last updated: November 5, 2026
Goal
Understand what UXP Backup/Restore avoids that a Velero restore of a Crossplane control plane risks, and what to know before relying on it.
Environment
Velero: Crossplane or UXP
UXP Backup/Restore: UXP v2 only (from v2.0.7-up.1, v2.1.4-up.1 and v2.2.0-up.1 on those lines), not UXP v1 or upstream Crossplane
The
LegacyClusterXRD risk applies only to Crossplane v2, which serves XRDs under two API versionsConfirmed with provider-nop on kind (Kubernetes v1.37, Crossplane v2.4.2, Velero v1.18.4, UXP v2.4.2-up.1). Duplicate cloud resources were also confirmed with provider-aws-ec2 v2.9.0 on EKS 1.33 (Velero v1.18.2). The UXP backup
forbiddenfailure was reproduced on UXP v2.1.4-up.2. Not tested on Crossplane v1Not covered: Spaces control plane backups, Space-level backups and Azure Backup for AKS
Recommendation
We recommend UXP Backup/Restore for Crossplane control planes. It restores packages and XRDs first, waits until they are ready, then imports claims, XRs and managed resources paused, so with GitOps paused nothing composes or touches cloud resources until all objects are back. Velero has NONE of these safeguards: a default Velero restore can create duplicate cloud resources and break composition while reporting Completed. If you stay on Velero, or only have a Velero backup, follow How do I back up and restore a Crossplane v2 control plane with Velero?
A default Velero restore can create duplicate cloud resources and still report Completed. Contact support before deleting any of them: deleting the wrong managed resource also deletes the real cloud resource.
Top risks of restoring Crossplane with Velero
Duplicate cloud resources. If Crossplane runs during the restore, claims restored before their XRs compose new managed resources, and so can XRs reconciled before their managed resources are restored. Those with generated external names can create new cloud resources, and the originals are left without an owner. On EKS with provider-aws, a default restore created 3 extra VPCs and 2 extra subnets within 20 seconds.
LegacyClusterXRDs fail to restore (Crossplane v2 only). Velero archives XRDs atv2, which rejectsspec.scope: LegacyCluster, the default for XRDs created asapiextensions.crossplane.io/v1. If those XRDs are not already on the target, the restore endsPartiallyFailed; claims and XRs of those types come back with nothing reconciling them.Composition breaks a few minutes later. If Crossplane is installed on the target before the restore but its providers and functions are not, Velero restores package TLS Secrets signed by the source's root CA next to the target's new one. About 2 minutes after the restore, composition fails with
x509: certificate signed by unknown authority.Backups silently miss new types. A backup taken within 5 minutes of a provider install or XRD creation ends
Completedwith no errors or warnings, without objects of the new types.Completeddoes not mean it worked. Velero does not pause Crossplane, restores types in its own order and runs no post-restore health check.
The Velero article avoids the first four with a manual procedure: restart Velero before backups, pause GitOps, install Crossplane, its packages and XRDs first or use a resource modifier, and keep Crossplane at 0 replicas and exclude pods and ReplicaSets during the restore.
Comparison
Velero, default restore | Velero, with the procedure | UXP Backup/Restore | |
|---|---|---|---|
Duplicate managed and cloud resources | yes, if Crossplane runs during the restore | avoided: Crossplane kept at 0, pods and ReplicaSets excluded | not observed: objects imported paused |
| restore | avoided: XRDs applied from Git, or restored at | restore stalls until you apply them from Git |
Package TLS | broken if Crossplane is pre-installed and packages are restored | avoided: packages installed first, or the root CA restored too | not affected: the target issues its own |
Types missing from the backup | within 5 minutes of a CRD change | avoided: Velero restarted before the backup | not tested |
| yes, no health check | no health check; verify by hand | yes, for restores by plain backup name |
Manual steps | none | pause GitOps, install Crossplane and packages from Git or add a resource modifier, scale Crossplane down and up, restart Velero before backups | pause GitOps, apply |
Scope | any Kubernetes resource, plus persistent volumes | same, but file-system volume restores need a separate restore | Crossplane and Upbound resources, package- and XRD-owned types, Secrets and ConfigMaps |
Before you rely on UXP Backup/Restore
Restore by the run name you recorded at backup time. Each run is stored as
<backup-name>--<YYYYMMDD-HHMMSS>. Every restore writes an extra, partial run under the same backup name, and a restore by plain name can pick it: it reportsCompleted, but objects are missing and the rest stay paused.Apply
LegacyClusterXRDs from Git before restoring. Without them theRestorekeeps retrying and imports nothing after the XRDs.Check that the first backup completes. It can fail with
forbiddenon Crossplane types the backup cannot list: on some UXP versions function input types such asresources.pt.fn.crossplane.io, on any version other*.crossplane.iotypes no package installed, such asclustermetrics.metrics.crossplane.io. Contact support for the RBAC fix.Pause GitOps for claims and XRs yourself. UXP does not do it for you.
Restore into a control plane on the same UXP version. Restoring into another control plane requires matching UXP versions.
ProviderConfigUsages come back without their owner, as with Velero. See ProviderConfigUsages stuck in deletion.
Back up other workloads and persistent volumes with another tool.
Fixes for the first three are in progress; contact support for status. The full UXP restore steps are in the Velero article, under "If you use UXP Backup/Restore".
Related
How do I back up and restore a Crossplane v2 control plane with Velero?: procedures, symptoms and fixes for every risk above