Custom Resource Schemas
CRD structure, field validation rules, and status conditions for site recovery resources
This page documents the structure, field validation rules, and status conditions for all Custom Resource Definitions (CRDs) used by Site Recovery. Understanding these schemas lets you author valid manifests, interpret controller-reported status, and build automation around the lifecycle of protection, failover, and replication health. Each CRD is described with its spec fields, accepted values and constraints, and the status subresource conditions that controllers write back as they reconcile your desired state.
Before working with Site Recovery CRDs, ensure the following are in place:
- Kubernetes ≥ 1.28 on all clusters (quorum, primary, and DR)
- KubeVirt ≥ 1.0 installed on primary and DR clusters
- DRBD kernel module ≥ 9.0 on worker nodes that host replicated volumes
- kubectl configured with access to the target cluster
- Site Recovery controllers deployed on the quorum cluster (failover-controller, protection-controller, pg-sync-controller)
- protection-group-controller and test-failover-controller deployed on primary and DR clusters
- replication-monitor deployed on primary and DR clusters (deployed automatically by the standard Ansible playbooks)
- For DRBD Operator deployments: DRBD Operator installed on both primary and DR clusters
- VolumeSnapshot support (CSI snapshotter) on primary and DR clusters if you intend to use TestFailover resources
- Familiarity with Kubernetes custom resources and
kubectl applyworkflows
The CRDs are installed automatically as part of the Site Recovery deployment playbooks. You do not apply them manually. The steps below show how to verify that all CRDs are present after deployment and how to inspect their schemas.
Step 1 — Confirm CRDs are registered on the quorum cluster
kubectl get crds | grep site-recovery
Expected output lists the following CRDs (group names may vary by your installation):
protectiongroups.<group>
protectionrequests.<group>
failoverrequests.<group>
testfailovers.<group>
drbdreplicationpolicies.<group>
drbdvolumes.<group>
rpoevents.<group>
replicationgroupstatuses.<group>
Step 2 — Inspect the OpenAPI schema for a specific CRD
kubectl explain protectiongroup --recursive
kubectl explain protectionrequest.spec --recursive
Step 3 — Confirm CRDs are registered on primary and DR clusters
ProtectionGroup, TestFailover, DRBDVolume, DRBDReplicationPolicy, and ReplicationGroupStatus resources are also watched on primary and DR clusters. Verify:
# Run on primary cluster
kubectl --kubeconfig /path/to/primary-kubeconfig.yaml get crds | grep site-recovery
# Run on DR cluster
kubectl --kubeconfig /path/to/dr-kubeconfig.yaml get crds | grep site-recovery
Step 4 — Validate a manifest before applying
Use pgctl to validate a resource manifest against the registered schema:
pgctl validate -f my-protection-group.yaml
The following sections describe every CRD spec field, its type, validation constraints, default value (where applicable), and behavioral effect. Status fields written by controllers are listed separately under each CRD.
ProtectionGroup
A ProtectionGroup declares which VMs should fail over together as a coordinated unit and tracks their collective replication state. It is used in centralized storage deployments. The protection-group-controller on the primary and DR clusters reconciles this resource; the pg-sync-controller on the quorum cluster keeps both sides synchronized.
Spec fields
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
vmNames | []string | Yes | Non-empty list | Names of VMs in the same namespace that belong to this group. All VMs must exist before protection can be established. |
namespace | string | Yes | Valid DNS label | Namespace on the primary cluster where the listed VMs reside. |
drNamespace | string | No | Valid DNS label | Namespace on the DR cluster where standby VM specs are maintained. Defaults to the same value as namespace. |
replicationPolicyRef | string | No | Name of a DRBDReplicationPolicy | For DRBD Operator deployments, the name of the DRBDReplicationPolicy to apply to all volumes in this group. |
consistencyMode | string | No | Strict | BestEffort | Controls whether failover is blocked when any VM in the group is not fully synced. Strict blocks failover; BestEffort proceeds with a warning. Defaults to Strict. |
Status fields
| Field | Type | Description |
|---|---|---|
phase | string | Aggregate replication state: Syncing, Consistent, or Degraded. |
conditions | []Condition | Standard Kubernetes condition list. Condition types include Ready, AllVMsProtected, and ReplicationHealthy. |
vmStatuses | []VMStatus | Per-VM replication state within the group. Each entry includes vmName, phase, and lastSyncTime. |
lastTransitionTime | string | RFC 3339 timestamp of the last phase transition. |
ProtectionRequest
A ProtectionRequest requests DR protection for a single VM in DRBD Operator deployments. The protection-controller on the quorum cluster drives the resource through a defined lifecycle: validation → DRBDVolume creation → sync wait → frontend PVC switchover → protected.
Spec fields
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
vmName | string | Yes | Non-empty | Name of the VM to protect. The VM must be running on the primary cluster. |
vmNamespace | string | Yes | Valid DNS label | Namespace of the VM on the primary cluster. |
replicationPolicyRef | string | Yes | Name of a DRBDReplicationPolicy | The replication policy that defines how the VM's volumes are replicated. |
protectionGroupRef | string | No | Name of a ProtectionGroup | If set, associates this VM with a Protection Group after protection is established. |
Status fields
| Field | Type | Description |
|---|---|---|
phase | string | Current lifecycle phase: Validating, CreatingVolumes, WaitingForSync, SwitchingFrontend, Protected, or Failed. |
conditions | []Condition | Condition types include VMValidated, VolumesCreated, ReplicationEstablished, FrontendSwitched. |
drbdVolumeRefs | []string | Names of DRBDVolume resources created for this VM's PVCs. |
frontendPVCRefs | []string | Names of the DRBD-backed frontend PVCs that replaced the VM's original PVCs. |
message | string | Human-readable description of the current state or failure reason. |
FailoverRequest
A FailoverRequest triggers a planned or unplanned failover for a Protection Group. The failover-controller on the quorum cluster watches for this resource and orchestrates the full failover sequence: VM shutdown (planned only), volume promotion on the DR cluster, and VM startup.
Spec fields
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
protectionGroupRef | string | Yes | Name of an existing ProtectionGroup | The Protection Group to fail over. |
type | string | Yes | Planned | Unplanned | Planned performs a graceful VM shutdown before promoting DR volumes, guaranteeing zero data loss. Unplanned promotes volumes immediately without a graceful shutdown, for use when the primary cluster is unavailable. |
targetNamespace | string | No | Valid DNS label | Namespace on the DR cluster where VMs should start. Defaults to the namespace declared in the ProtectionGroup. |
force | boolean | No | — | When true on an Unplanned failover, skips reachability checks for the primary cluster. Use only when the primary is confirmed unreachable. Defaults to false. |
Status fields
| Field | Type | Description |
|---|---|---|
phase | string | Operation phase: Pending, ShuttingDownVMs, PromotingVolumes, StartingVMs, Completed, or Failed. |
conditions | []Condition | Condition types include VMsShutdown, VolumesPromoted, VMsStarted. |
startTime | string | RFC 3339 timestamp when the failover-controller began processing. |
completionTime | string | RFC 3339 timestamp when the operation reached Completed or Failed. |
message | string | Human-readable status or failure reason. |
TestFailover
A TestFailover initiates a non-disruptive DR validation run. The test-failover-controller on the primary and DR clusters orchestrates snapshot creation, test VM provisioning on the DR cluster, verification checks, and cleanup — without affecting production workloads. TestFailover is supported only for DRBD Operator deployment models.
Spec fields
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
protectionGroupRef | string | Yes | Name of an existing ProtectionGroup | The Protection Group whose volumes are snapshotted for the test. |
testNamespace | string | No | Valid DNS label | Namespace on the DR cluster where test VMs are created. Defaults to <protectionGroupRef>-test. |
snapshotClass | string | No | Name of a VolumeSnapshotClass | The CSI snapshot class to use when snapshotting volumes. If omitted, the cluster default is used. |
autoCleanup | boolean | No | — | When true, the controller removes test VMs and snapshots after verification completes. Defaults to true. |
verificationTimeoutSeconds | integer | No | ≥ 60 | How long the controller waits for test VMs to reach Running state before marking the test as failed. Defaults to 300. |
Status fields
| Field | Type | Description |
|---|---|---|
phase | string | Lifecycle phase: CreatingSnapshots, ProvisioningTestVMs, Verifying, CleaningUp, Succeeded, or Failed. |
conditions | []Condition | Condition types include SnapshotsCreated, TestVMsRunning, VerificationPassed, CleanupComplete. |
snapshotRefs | []string | Names of VolumeSnapshot resources created during the test. |
testVMRefs | []string | Names of test VM resources created on the DR cluster. |
startTime | string | RFC 3339 timestamp when the test began. |
completionTime | string | RFC 3339 timestamp when the test reached a terminal phase. |
message | string | Human-readable result or failure reason. |
DRBDReplicationPolicy
A DRBDReplicationPolicy defines cross-cluster replication settings for DRBD Operator deployments. The DRBD Operator on primary and DR clusters reads this resource to configure DRBD protocol, storage class mappings, and replication endpoints.
Spec fields
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
protocol | string | Yes | A | C | DRBD replication protocol. C (synchronous) acknowledges writes only after both sides commit; requires < 50 ms RTT and achieves RPO=0. A (asynchronous) acknowledges after local commit; suitable for high-latency links; achieves near-zero RPO. |
storageClassMappings | []StorageClassMapping | Yes | Non-empty list | Pairs a primary-cluster storage class name with the corresponding DR-cluster storage class name. |
storageClassMappings[].primaryStorageClass | string | Yes | Non-empty | Storage class name on the primary cluster. |
storageClassMappings[].drStorageClass | string | Yes | Non-empty | Storage class name on the DR cluster. |
replicationEndpoints | []ReplicationEndpoint | Yes | Non-empty list | IP addresses or hostnames of worker nodes participating in DRBD replication. Must be reachable over TCP ports 7000–7999. |
replicationEndpoints[].address | string | Yes | Valid IP or hostname | Replication endpoint address. |
replicationEndpoints[].port | integer | No | 7000–7999 | DRBD replication port. Defaults to 7789. |
autoRepair | boolean | No | — | When true, the DRBD Operator attempts automatic resync after a split-brain is detected. Defaults to false; manual intervention is recommended for split-brain resolution. |
Status fields
| Field | Type | Description |
|---|---|---|
phase | string | Policy status: Active, Degraded, or Invalid. |
conditions | []Condition | Condition types include EndpointsReachable, StorageClassesValid. |
message | string | Human-readable status or validation error. |
DRBDVolume
A DRBDVolume represents a single DRBD-replicated PVC. It is created automatically by the protection-controller when a ProtectionRequest is processed. You inspect DRBDVolume resources to verify per-volume replication status; you do not typically create them by hand.
Spec fields
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
sourcePVCRef | string | Yes | Name of an existing PVC | The original PVC on the primary cluster that is being replicated. |
sourceNamespace | string | Yes | Valid DNS label | Namespace of the source PVC. |
replicationPolicyRef | string | Yes | Name of a DRBDReplicationPolicy | The policy governing this volume's replication behavior. |
Status fields
| Field | Type | Description |
|---|---|---|
phase | string | Volume replication state: Provisioning, Syncing, UpToDate, Degraded, or Failed. |
syncProgress | integer | Percentage of data synchronized to the DR cluster (0–100). |
frontendPVCRef | string | Name of the DRBD-backed frontend PVC that replaced the VM's original PVC on the primary cluster. |
drPVCRef | string | Name of the standby PVC on the DR cluster that receives replicated data. |
lastSyncTime | string | RFC 3339 timestamp of the most recent successful sync. |
conditions | []Condition | Condition types include ReplicationEstablished, UpToDate. |
RPOEvent
An RPOEvent records a replication lag violation — an instance where the observed lag between primary and DR exceeded the acceptable threshold. The replication-monitor agent creates these resources; you read them for auditing and alerting.
Spec fields
RPOEvent resources are created exclusively by the replication-monitor. The spec fields are set at creation time and are immutable.
| Field | Type | Description |
|---|---|---|
protectionGroupRef | string | Name of the Protection Group affected by the lag violation. |
observedLagSeconds | integer | The replication lag observed at the time of the event, in seconds. |
threshold | integer | The lag threshold (in seconds) that was exceeded, as configured in the replication-monitor. |
severity | string | Event severity: Warning or Critical. |
timestamp | string | RFC 3339 timestamp when the violation was detected. |
affectedVolumes | []string | Names of DRBDVolume resources that were lagging at the time of the event. |
Status fields
RPOEvent has no controller-managed status subresource. The full record is contained in the spec.
ReplicationGroupStatus
A ReplicationGroupStatus provides an aggregated replication health summary for a Protection Group. The replication-monitor agent creates and updates these resources so that operators and the failover-controller can assess group-level readiness without inspecting individual DRBDVolume resources.
Spec fields
ReplicationGroupStatus resources are maintained by the replication-monitor. The fields below are written by the agent and are not user-editable.
| Field | Type | Description |
|---|---|---|
protectionGroupRef | string | Name of the Protection Group this status describes. |
overallHealth | string | Aggregated health: Healthy, Degraded, or Critical. |
perVolumeStatus | []VolumeStatus | Per-volume sync state. Each entry includes volumeName, phase, and syncProgress. |
lastSuccessfulSyncTime | string | RFC 3339 timestamp of the most recent point at which all volumes in the group were fully synchronized. |
message | string | Human-readable summary of the current health state. |
The following patterns represent the most common ways you will interact with Site Recovery CRDs during day-to-day operations.
Protecting a VM with a ProtectionRequest (DRBD Operator model)
Create a ProtectionRequest to request DRBD-backed protection for a single VM. The protection-controller picks up the resource and drives it through validation, volume creation, sync, and frontend PVC switchover.
apiVersion: site-recovery.example.com/v1alpha1
kind: ProtectionRequest
metadata:
name: protect-vm-web01
namespace: dr-production
spec:
vmName: web01
vmNamespace: production
replicationPolicyRef: policy-production
protectionGroupRef: pg-production-web
Watch the status phase progress:
kubectl get protectionrequest protect-vm-web01 -n dr-production -w
Grouping VMs into a Protection Group
Declare a ProtectionGroup to ensure that a set of VMs always fails over together. The protection-group-controller and pg-sync-controller keep this resource reconciled on both clusters.
apiVersion: site-recovery.example.com/v1alpha1
kind: ProtectionGroup
metadata:
name: pg-production-web
namespace: dr-production
spec:
vmNames:
- web01
- web02
- db01
namespace: production
replicationPolicyRef: policy-production
consistencyMode: Strict
Inspecting replication health
Read the ReplicationGroupStatus for a group to get an aggregated view without querying each DRBDVolume individually:
kubectl get replicationgroupstatus -n dr-production -o yaml
Check per-volume sync progress by listing DRBDVolume resources:
kubectl get drbdvolume -n dr-production
Triggering a planned failover
Create a FailoverRequest with type: Planned. The failover-controller gracefully stops VMs on the primary cluster before promoting volumes on the DR cluster.
apiVersion: site-recovery.example.com/v1alpha1
kind: FailoverRequest
metadata:
name: failover-production-planned
namespace: dr-production
spec:
protectionGroupRef: pg-production-web
type: Planned
Alternatively, use pgctl to trigger the same operation:
pgctl failover --group pg-production-web --type planned --deployment production
Triggering an unplanned failover
When the primary cluster is unavailable, set type: Unplanned and optionally force: true to bypass primary reachability checks:
apiVersion: site-recovery.example.com/v1alpha1
kind: FailoverRequest
metadata:
name: failover-production-emergency
namespace: dr-production
spec:
protectionGroupRef: pg-production-web
type: Unplanned
force: true
Running a non-disruptive test failover
Create a TestFailover resource to validate DR readiness without affecting production. This requires VolumeSnapshot support on both clusters and is only available for DRBD Operator deployments.
apiVersion: site-recovery.example.com/v1alpha1
kind: TestFailover
metadata:
name: test-production-web
namespace: dr-production
spec:
protectionGroupRef: pg-production-web
autoCleanup: true
verificationTimeoutSeconds: 300
Auditing RPO violations
List all RPOEvent resources to review recent replication lag violations:
kubectl get rpoevent -n dr-production --sort-by=.spec.timestamp
Example 1 — Define a DRBDReplicationPolicy for synchronous replication
This policy configures Protocol C (synchronous) replication between two clusters, mapping their respective storage classes and declaring the replication endpoints.
apiVersion: site-recovery.example.com/v1alpha1
kind: DRBDReplicationPolicy
metadata:
name: policy-production
namespace: dr-production
spec:
protocol: C
storageClassMappings:
- primaryStorageClass: fast-ssd
drStorageClass: fast-ssd-dr
replicationEndpoints:
- address: 10.0.1.10
port: 7789
- address: 10.0.1.11
port: 7789
autoRepair: false
Verify the policy is active:
kubectl get drbdreplicationpolicy policy-production -n dr-production -o jsonpath='{.status.phase}'
Expected output:
Active
Example 2 — Create a ProtectionRequest and track its lifecycle
apiVersion: site-recovery.example.com/v1alpha1
kind: ProtectionRequest
metadata:
name: protect-vm-db01
namespace: dr-production
spec:
vmName: db01
vmNamespace: production
replicationPolicyRef: policy-production
Apply and watch the phase transitions:
kubectl apply -f protect-vm-db01.yaml
kubectl get protectionrequest protect-vm-db01 -n dr-production -w
Expected phase sequence:
NAME PHASE
protect-vm-db01 Validating
protect-vm-db01 CreatingVolumes
protect-vm-db01 WaitingForSync
protect-vm-db01 SwitchingFrontend
protect-vm-db01 Protected
Inspect the resulting DRBDVolume references:
kubectl get protectionrequest protect-vm-db01 -n dr-production \
-o jsonpath='{.status.drbdVolumeRefs}'
Example 3 — ProtectionGroup with Strict consistency and multiple VMs
apiVersion: site-recovery.example.com/v1alpha1
kind: ProtectionGroup
metadata:
name: pg-production-web
namespace: dr-production
spec:
vmNames:
- web01
- web02
- db01
namespace: production
replicationPolicyRef: policy-production
consistencyMode: Strict
Check the aggregated group phase:
kubectl get protectiongroup pg-production-web -n dr-production \
-o jsonpath='{.status.phase}'
Expected output when all VMs are fully synced:
Consistent
Example 4 — Planned failover and status monitoring
apiVersion: site-recovery.example.com/v1alpha1
kind: FailoverRequest
metadata:
name: failover-planned-20240115
namespace: dr-production
spec:
protectionGroupRef: pg-production-web
type: Planned
kubectl apply -f failover-planned-20240115.yaml
kubectl get failoverrequest failover-planned-20240115 -n dr-production -w
Expected phase sequence:
NAME PHASE
failover-planned-20240115 Pending
failover-planned-20240115 ShuttingDownVMs
failover-planned-20240115 PromotingVolumes
failover-planned-20240115 StartingVMs
failover-planned-20240115 Completed
Example 5 — Non-disruptive test failover (DRBD Operator model only)
apiVersion: site-recovery.example.com/v1alpha1
kind: TestFailover
metadata:
name: test-web-20240115
namespace: dr-production
spec:
protectionGroupRef: pg-production-web
testNamespace: pg-production-web-test
autoCleanup: true
verificationTimeoutSeconds: 300
kubectl apply -f test-web-20240115.yaml
kubectl get testfailover test-web-20240115 -n dr-production -w
Expected output on success:
NAME PHASE
test-web-20240115 CreatingSnapshots
test-web-20240115 ProvisioningTestVMs
test-web-20240115 Verifying
test-web-20240115 CleaningUp
test-web-20240115 Succeeded
Example 6 — Inspect RPO violations
kubectl get rpoevent -n dr-production -o custom-columns=\
NAME:.metadata.name,\
GROUP:.spec.protectionGroupRef,\
LAG:.spec.observedLagSeconds,\
SEVERITY:.spec.severity,\
TIME:.spec.timestamp
Example output:
NAME GROUP LAG SEVERITY TIME
rpo-evt-20240115a pg-production-web 47 Warning 2024-01-15T02:13:00Z
rpo-evt-20240115b pg-production-web 91 Critical 2024-01-15T02:47:00Z
Use the following format for each issue: Symptom → Likely cause → Fix.
ProtectionRequest stuck in Validating phase
Symptom: A ProtectionRequest remains in Validating for more than a few minutes. The message field may say the VM cannot be found or is not in a running state.
Likely cause: The VM named in spec.vmName does not exist in spec.vmNamespace on the primary cluster, or the VM is in a stopped or error state.
Fix: Confirm the VM exists and is running:
kubectl get vm <vmName> -n <vmNamespace> --kubeconfig /path/to/primary-kubeconfig.yaml
Correct the vmName or vmNamespace in the ProtectionRequest, or start the VM before re-applying.
ProtectionRequest stuck in WaitingForSync phase
Symptom: The ProtectionRequest has been in WaitingForSync for an extended period. The corresponding DRBDVolume shows a syncProgress value that is not advancing.
Likely cause: Network connectivity between primary and DR worker nodes on DRBD replication ports (TCP 7000–7999) is blocked or degraded, or the replication endpoint addresses in the DRBDReplicationPolicy are incorrect.
Fix: Verify network connectivity:
# From a primary worker node
nc -zv <dr-worker-ip> 7789
Confirm the replicationEndpoints in the DRBDReplicationPolicy match the actual DR worker node addresses. Check DRBD kernel module status on both sides with dmesg | grep drbd.
ProtectionGroup phase is Degraded
Symptom: kubectl get protectiongroup shows Degraded. The Site Manager UI shows a red health indicator for the group. RPOEvents may be present.
Likely cause: One or more DRBDVolume resources in the group are not UpToDate. This can result from a transient network issue, a node restart, or a replication lag threshold violation detected by the replication-monitor.
Fix: Identify which volumes are degraded:
kubectl get drbdvolume -n dr-production
Check the ReplicationGroupStatus for the group:
kubectl get replicationgroupstatus -n dr-production -o yaml
If a DRBDVolume is in Degraded state, inspect its events and the replication-monitor logs for the root cause. If sync is stalled, refer to the node and replication diagnostics guide.
FailoverRequest stuck in ShuttingDownVMs phase (planned failover)
Symptom: A planned FailoverRequest does not progress past ShuttingDownVMs. VMs on the primary cluster appear to still be running.
Likely cause: One or more VMs in the Protection Group are not responding to graceful shutdown requests, or the failover-controller cannot reach the primary cluster API server.
Fix: Verify primary cluster API connectivity from the quorum cluster:
kubectl get nodes --kubeconfig /path/to/primary-kubeconfig.yaml
Check failover-controller logs on the quorum cluster:
kubectl logs -n dr-production -l app=failover-controller --tail=100
If VMs are unresponsive to shutdown, consider deleting the FailoverRequest and re-creating it with type: Unplanned if the situation warrants emergency failover.
TestFailover fails in ProvisioningTestVMs phase
Symptom: A TestFailover resource enters Failed phase during ProvisioningTestVMs. The message field references snapshot or PVC provisioning errors.
Likely cause: VolumeSnapshot support (CSI snapshotter) is not installed or the specified snapshotClass does not exist on the DR cluster. TestFailover is only supported for DRBD Operator deployment models.
Fix: Confirm VolumeSnapshot CRDs and the CSI snapshotter are present on the DR cluster:
kubectl get crd volumesnapshots.snapshot.storage.k8s.io \
--kubeconfig /path/to/dr-kubeconfig.yaml
kubectl get volumesnapshotclass \
--kubeconfig /path/to/dr-kubeconfig.yaml
If the snapshotClass field is set in the TestFailover spec, ensure the named class exists. Remove the field to use the cluster default.
DRBDReplicationPolicy shows phase Invalid
Symptom: A DRBDReplicationPolicy resource reports phase: Invalid in its status. The message field describes a validation failure.
Likely cause: A referenced storage class name does not exist on one of the clusters, or a replication endpoint is not reachable on the configured port.
Fix: Check the status message for specifics:
kubectl get drbdreplicationpolicy policy-production -n dr-production \
-o jsonpath='{.status.message}'
Verify storage classes exist on both clusters:
kubectl get sc --kubeconfig /path/to/primary-kubeconfig.yaml
kubectl get sc --kubeconfig /path/to/dr-kubeconfig.yaml
Correct the storageClassMappings or replicationEndpoints and re-apply the policy.
pgctl validate reports schema errors
Symptom: Running pgctl validate -f <manifest> outputs field validation errors before you apply a resource.
Likely cause: A required field is missing, an enum value is incorrect (for example, protocol: B instead of A or C), or a cross-reference (such as replicationPolicyRef) names a resource that does not yet exist.
Fix: Review the field tables in the Configuration section above. Use kubectl explain <kind>.spec.<field> for inline schema documentation. Ensure referenced resources (ProtectionGroup, DRBDReplicationPolicy) exist in the target namespace before applying dependent resources.