diff --git a/apis/hive/v1/clusterclaim_types.go b/apis/hive/v1/clusterclaim_types.go
index 449d63afec2..7bb772d0143 100644
--- a/apis/hive/v1/clusterclaim_types.go
+++ b/apis/hive/v1/clusterclaim_types.go
@@ -24,9 +24,13 @@ type ClusterClaimSpec struct {
 	// Lifetime is the maximum lifetime of the claim after it is assigned a cluster. If the claim still exists
 	// when the lifetime has elapsed, the claim will be deleted by Hive.
 	// This is a Duration value; see https://pkg.go.dev/time#ParseDuration for accepted formats.
+	// Note: due to discrepancies in validation vs parsing, we use a Pattern instead of `Format=duration`. See
+	// https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+	// https://github.com/kubernetes/apimachinery/issues/131
+	// https://github.com/kubernetes/apiextensions-apiserver/issues/56
 	// +optional
 	// +kubebuilder:validation:Type=string
-	// +kubebuilder:validation:Format=duration
+	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
 	Lifetime *metav1.Duration `json:"lifetime,omitempty"`
 }
 
diff --git a/apis/hive/v1/clusterdeployment_types.go b/apis/hive/v1/clusterdeployment_types.go
index f037b04f7f3..d19afc0e7af 100644
--- a/apis/hive/v1/clusterdeployment_types.go
+++ b/apis/hive/v1/clusterdeployment_types.go
@@ -145,9 +145,13 @@ type ClusterDeploymentSpec struct {
 	// given duration. The time that a cluster has been running is the time since the cluster was installed or the
 	// time since the cluster last came out of hibernation.
 	// This is a Duration value; see https://pkg.go.dev/time#ParseDuration for accepted formats.
+	// Note: due to discrepancies in validation vs parsing, we use a Pattern instead of `Format=duration`. See
+	// https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+	// https://github.com/kubernetes/apimachinery/issues/131
+	// https://github.com/kubernetes/apiextensions-apiserver/issues/56
 	// +optional
 	// +kubebuilder:validation:Type=string
-	// +kubebuilder:validation:Format=duration
+	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
 	HibernateAfter *metav1.Duration `json:"hibernateAfter,omitempty"`
 
 	// InstallAttemptsLimit is the maximum number of times Hive will attempt to install the cluster.
diff --git a/apis/hive/v1/clusterpool_types.go b/apis/hive/v1/clusterpool_types.go
index ffc8cc3a8bf..c45a746082e 100644
--- a/apis/hive/v1/clusterpool_types.go
+++ b/apis/hive/v1/clusterpool_types.go
@@ -62,9 +62,13 @@ type ClusterPoolSpec struct {
 	// that a cluster has been running is the time since the cluster was installed or the time since the cluster last came
 	// out of hibernation.
 	// This is a Duration value; see https://pkg.go.dev/time#ParseDuration for accepted formats.
+	// Note: due to discrepancies in validation vs parsing, we use a Pattern instead of `Format=duration`. See
+	// https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+	// https://github.com/kubernetes/apimachinery/issues/131
+	// https://github.com/kubernetes/apiextensions-apiserver/issues/56
 	// +optional
 	// +kubebuilder:validation:Type=string
-	// +kubebuilder:validation:Format=duration
+	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
 	HibernateAfter *metav1.Duration `json:"hibernateAfter,omitempty"`
 
 	// SkipMachinePools allows creating clusterpools where the machinepools are not managed by hive after cluster creation
@@ -80,18 +84,26 @@ type ClusterPoolSpec struct {
 type ClusterPoolClaimLifetime struct {
 	// Default is the default lifetime of the claim when no lifetime is set on the claim itself.
 	// This is a Duration value; see https://pkg.go.dev/time#ParseDuration for accepted formats.
+	// Note: due to discrepancies in validation vs parsing, we use a Pattern instead of `Format=duration`. See
+	// https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+	// https://github.com/kubernetes/apimachinery/issues/131
+	// https://github.com/kubernetes/apiextensions-apiserver/issues/56
 	// +optional
 	// +kubebuilder:validation:Type=string
-	// +kubebuilder:validation:Format=duration
+	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
 	Default *metav1.Duration `json:"default,omitempty"`
 
 	// Maximum is the maximum lifetime of the claim after it is assigned a cluster. If the claim still exists
 	// when the lifetime has elapsed, the claim will be deleted by Hive.
 	// The lifetime of a claim is the mimimum of the lifetimes set by the cluster pool and the claim itself.
 	// This is a Duration value; see https://pkg.go.dev/time#ParseDuration for accepted formats.
+	// Note: due to discrepancies in validation vs parsing, we use a Pattern instead of `Format=duration`. See
+	// https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+	// https://github.com/kubernetes/apimachinery/issues/131
+	// https://github.com/kubernetes/apiextensions-apiserver/issues/56
 	// +optional
 	// +kubebuilder:validation:Type=string
-	// +kubebuilder:validation:Format=duration
+	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
 	Maximum *metav1.Duration `json:"maximum,omitempty"`
 }
 
diff --git a/config/crds/hive.openshift.io_clusterclaims.yaml b/config/crds/hive.openshift.io_clusterclaims.yaml
index e05cd5ac00f..f49dddbc060 100644
--- a/config/crds/hive.openshift.io_clusterclaims.yaml
+++ b/config/crds/hive.openshift.io_clusterclaims.yaml
@@ -55,11 +55,14 @@ spec:
                   which to claim a cluster.
                 type: string
               lifetime:
-                description: Lifetime is the maximum lifetime of the claim after it
-                  is assigned a cluster. If the claim still exists when the lifetime
+                description: 'Lifetime is the maximum lifetime of the claim after
+                  it is assigned a cluster. If the claim still exists when the lifetime
                   has elapsed, the claim will be deleted by Hive. This is a Duration
                   value; see https://pkg.go.dev/time#ParseDuration for accepted formats.
-                format: duration
+                  Note: due to discrepancies in validation vs parsing, we use a Pattern
+                  instead of `Format=duration`. See https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+                  https://github.com/kubernetes/apimachinery/issues/131 https://github.com/kubernetes/apiextensions-apiserver/issues/56'
+                pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
                 type: string
               namespace:
                 description: Namespace is the namespace containing the ClusterDeployment
diff --git a/config/crds/hive.openshift.io_clusterdeployments.yaml b/config/crds/hive.openshift.io_clusterdeployments.yaml
index 765a87b78cf..dc18eec45b3 100644
--- a/config/crds/hive.openshift.io_clusterdeployments.yaml
+++ b/config/crds/hive.openshift.io_clusterdeployments.yaml
@@ -242,13 +242,15 @@ spec:
                     type: object
                 type: object
               hibernateAfter:
-                description: HibernateAfter will transition a cluster to hibernating
+                description: 'HibernateAfter will transition a cluster to hibernating
                   power state after it has been running for the given duration. The
                   time that a cluster has been running is the time since the cluster
                   was installed or the time since the cluster last came out of hibernation.
                   This is a Duration value; see https://pkg.go.dev/time#ParseDuration
-                  for accepted formats.
-                format: duration
+                  for accepted formats. Note: due to discrepancies in validation vs
+                  parsing, we use a Pattern instead of `Format=duration`. See https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+                  https://github.com/kubernetes/apimachinery/issues/131 https://github.com/kubernetes/apiextensions-apiserver/issues/56'
+                pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
                 type: string
               ingress:
                 description: Ingress allows defining desired clusteringress/shards
diff --git a/config/crds/hive.openshift.io_clusterpools.yaml b/config/crds/hive.openshift.io_clusterpools.yaml
index 73e0e272fa1..a1107e7265f 100644
--- a/config/crds/hive.openshift.io_clusterpools.yaml
+++ b/config/crds/hive.openshift.io_clusterpools.yaml
@@ -67,30 +67,39 @@ spec:
                   cluster pool.
                 properties:
                   default:
-                    description: Default is the default lifetime of the claim when
+                    description: 'Default is the default lifetime of the claim when
                       no lifetime is set on the claim itself. This is a Duration value;
                       see https://pkg.go.dev/time#ParseDuration for accepted formats.
-                    format: duration
+                      Note: due to discrepancies in validation vs parsing, we use
+                      a Pattern instead of `Format=duration`. See https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+                      https://github.com/kubernetes/apimachinery/issues/131 https://github.com/kubernetes/apiextensions-apiserver/issues/56'
+                    pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
                     type: string
                   maximum:
-                    description: Maximum is the maximum lifetime of the claim after
+                    description: 'Maximum is the maximum lifetime of the claim after
                       it is assigned a cluster. If the claim still exists when the
                       lifetime has elapsed, the claim will be deleted by Hive. The
                       lifetime of a claim is the mimimum of the lifetimes set by the
                       cluster pool and the claim itself. This is a Duration value;
                       see https://pkg.go.dev/time#ParseDuration for accepted formats.
-                    format: duration
+                      Note: due to discrepancies in validation vs parsing, we use
+                      a Pattern instead of `Format=duration`. See https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+                      https://github.com/kubernetes/apimachinery/issues/131 https://github.com/kubernetes/apiextensions-apiserver/issues/56'
+                    pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
                     type: string
                 type: object
               hibernateAfter:
-                description: HibernateAfter will be applied to new ClusterDeployments
+                description: 'HibernateAfter will be applied to new ClusterDeployments
                   created for the pool. HibernateAfter will transition clusters in
                   the clusterpool to hibernating power state after it has been running
                   for the given duration. The time that a cluster has been running
                   is the time since the cluster was installed or the time since the
                   cluster last came out of hibernation. This is a Duration value;
                   see https://pkg.go.dev/time#ParseDuration for accepted formats.
-                format: duration
+                  Note: due to discrepancies in validation vs parsing, we use a Pattern
+                  instead of `Format=duration`. See https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+                  https://github.com/kubernetes/apimachinery/issues/131 https://github.com/kubernetes/apiextensions-apiserver/issues/56'
+                pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
                 type: string
               imageSetRef:
                 description: ImageSetRef is a reference to a ClusterImageSet. The
diff --git a/hack/app-sre/saas-template.yaml b/hack/app-sre/saas-template.yaml
index eae3e0b4365..1c2c6b78bc3 100644
--- a/hack/app-sre/saas-template.yaml
+++ b/hack/app-sre/saas-template.yaml
@@ -140,12 +140,14 @@ objects:
                     which to claim a cluster.
                   type: string
                 lifetime:
-                  description: Lifetime is the maximum lifetime of the claim after
+                  description: 'Lifetime is the maximum lifetime of the claim after
                     it is assigned a cluster. If the claim still exists when the lifetime
                     has elapsed, the claim will be deleted by Hive. This is a Duration
                     value; see https://pkg.go.dev/time#ParseDuration for accepted
-                    formats.
-                  format: duration
+                    formats. Note: due to discrepancies in validation vs parsing,
+                    we use a Pattern instead of `Format=duration`. See https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+                    https://github.com/kubernetes/apimachinery/issues/131 https://github.com/kubernetes/apiextensions-apiserver/issues/56'
+                  pattern: "^([0-9]+(\\.[0-9]+)?(ns|us|\xB5s|ms|s|m|h))+$"
                   type: string
                 namespace:
                   description: Namespace is the namespace containing the ClusterDeployment
@@ -495,13 +497,16 @@ objects:
                       type: object
                   type: object
                 hibernateAfter:
-                  description: HibernateAfter will transition a cluster to hibernating
+                  description: 'HibernateAfter will transition a cluster to hibernating
                     power state after it has been running for the given duration.
                     The time that a cluster has been running is the time since the
                     cluster was installed or the time since the cluster last came
                     out of hibernation. This is a Duration value; see https://pkg.go.dev/time#ParseDuration
-                    for accepted formats.
-                  format: duration
+                    for accepted formats. Note: due to discrepancies in validation
+                    vs parsing, we use a Pattern instead of `Format=duration`. See
+                    https://bugzilla.redhat.com/show_bug.cgi?id=2050332 https://github.com/kubernetes/apimachinery/issues/131
+                    https://github.com/kubernetes/apiextensions-apiserver/issues/56'
+                  pattern: "^([0-9]+(\\.[0-9]+)?(ns|us|\xB5s|ms|s|m|h))+$"
                   type: string
                 ingress:
                   description: Ingress allows defining desired clusteringress/shards
@@ -1762,33 +1767,39 @@ objects:
                     the cluster pool.
                   properties:
                     default:
-                      description: Default is the default lifetime of the claim when
+                      description: 'Default is the default lifetime of the claim when
                         no lifetime is set on the claim itself. This is a Duration
                         value; see https://pkg.go.dev/time#ParseDuration for accepted
-                        formats.
-                      format: duration
+                        formats. Note: due to discrepancies in validation vs parsing,
+                        we use a Pattern instead of `Format=duration`. See https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+                        https://github.com/kubernetes/apimachinery/issues/131 https://github.com/kubernetes/apiextensions-apiserver/issues/56'
+                      pattern: "^([0-9]+(\\.[0-9]+)?(ns|us|\xB5s|ms|s|m|h))+$"
                       type: string
                     maximum:
-                      description: Maximum is the maximum lifetime of the claim after
+                      description: 'Maximum is the maximum lifetime of the claim after
                         it is assigned a cluster. If the claim still exists when the
                         lifetime has elapsed, the claim will be deleted by Hive. The
                         lifetime of a claim is the mimimum of the lifetimes set by
                         the cluster pool and the claim itself. This is a Duration
                         value; see https://pkg.go.dev/time#ParseDuration for accepted
-                        formats.
-                      format: duration
+                        formats. Note: due to discrepancies in validation vs parsing,
+                        we use a Pattern instead of `Format=duration`. See https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+                        https://github.com/kubernetes/apimachinery/issues/131 https://github.com/kubernetes/apiextensions-apiserver/issues/56'
+                      pattern: "^([0-9]+(\\.[0-9]+)?(ns|us|\xB5s|ms|s|m|h))+$"
                       type: string
                   type: object
                 hibernateAfter:
-                  description: HibernateAfter will be applied to new ClusterDeployments
+                  description: 'HibernateAfter will be applied to new ClusterDeployments
                     created for the pool. HibernateAfter will transition clusters
                     in the clusterpool to hibernating power state after it has been
                     running for the given duration. The time that a cluster has been
                     running is the time since the cluster was installed or the time
                     since the cluster last came out of hibernation. This is a Duration
                     value; see https://pkg.go.dev/time#ParseDuration for accepted
-                    formats.
-                  format: duration
+                    formats. Note: due to discrepancies in validation vs parsing,
+                    we use a Pattern instead of `Format=duration`. See https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+                    https://github.com/kubernetes/apimachinery/issues/131 https://github.com/kubernetes/apiextensions-apiserver/issues/56'
+                  pattern: "^([0-9]+(\\.[0-9]+)?(ns|us|\xB5s|ms|s|m|h))+$"
                   type: string
                 imageSetRef:
                   description: ImageSetRef is a reference to a ClusterImageSet. The
diff --git a/vendor/github.com/openshift/hive/apis/hive/v1/clusterclaim_types.go b/vendor/github.com/openshift/hive/apis/hive/v1/clusterclaim_types.go
index 449d63afec2..7bb772d0143 100644
--- a/vendor/github.com/openshift/hive/apis/hive/v1/clusterclaim_types.go
+++ b/vendor/github.com/openshift/hive/apis/hive/v1/clusterclaim_types.go
@@ -24,9 +24,13 @@ type ClusterClaimSpec struct {
 	// Lifetime is the maximum lifetime of the claim after it is assigned a cluster. If the claim still exists
 	// when the lifetime has elapsed, the claim will be deleted by Hive.
 	// This is a Duration value; see https://pkg.go.dev/time#ParseDuration for accepted formats.
+	// Note: due to discrepancies in validation vs parsing, we use a Pattern instead of `Format=duration`. See
+	// https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+	// https://github.com/kubernetes/apimachinery/issues/131
+	// https://github.com/kubernetes/apiextensions-apiserver/issues/56
 	// +optional
 	// +kubebuilder:validation:Type=string
-	// +kubebuilder:validation:Format=duration
+	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
 	Lifetime *metav1.Duration `json:"lifetime,omitempty"`
 }
 
diff --git a/vendor/github.com/openshift/hive/apis/hive/v1/clusterdeployment_types.go b/vendor/github.com/openshift/hive/apis/hive/v1/clusterdeployment_types.go
index f037b04f7f3..d19afc0e7af 100644
--- a/vendor/github.com/openshift/hive/apis/hive/v1/clusterdeployment_types.go
+++ b/vendor/github.com/openshift/hive/apis/hive/v1/clusterdeployment_types.go
@@ -145,9 +145,13 @@ type ClusterDeploymentSpec struct {
 	// given duration. The time that a cluster has been running is the time since the cluster was installed or the
 	// time since the cluster last came out of hibernation.
 	// This is a Duration value; see https://pkg.go.dev/time#ParseDuration for accepted formats.
+	// Note: due to discrepancies in validation vs parsing, we use a Pattern instead of `Format=duration`. See
+	// https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+	// https://github.com/kubernetes/apimachinery/issues/131
+	// https://github.com/kubernetes/apiextensions-apiserver/issues/56
 	// +optional
 	// +kubebuilder:validation:Type=string
-	// +kubebuilder:validation:Format=duration
+	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
 	HibernateAfter *metav1.Duration `json:"hibernateAfter,omitempty"`
 
 	// InstallAttemptsLimit is the maximum number of times Hive will attempt to install the cluster.
diff --git a/vendor/github.com/openshift/hive/apis/hive/v1/clusterpool_types.go b/vendor/github.com/openshift/hive/apis/hive/v1/clusterpool_types.go
index ffc8cc3a8bf..c45a746082e 100644
--- a/vendor/github.com/openshift/hive/apis/hive/v1/clusterpool_types.go
+++ b/vendor/github.com/openshift/hive/apis/hive/v1/clusterpool_types.go
@@ -62,9 +62,13 @@ type ClusterPoolSpec struct {
 	// that a cluster has been running is the time since the cluster was installed or the time since the cluster last came
 	// out of hibernation.
 	// This is a Duration value; see https://pkg.go.dev/time#ParseDuration for accepted formats.
+	// Note: due to discrepancies in validation vs parsing, we use a Pattern instead of `Format=duration`. See
+	// https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+	// https://github.com/kubernetes/apimachinery/issues/131
+	// https://github.com/kubernetes/apiextensions-apiserver/issues/56
 	// +optional
 	// +kubebuilder:validation:Type=string
-	// +kubebuilder:validation:Format=duration
+	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
 	HibernateAfter *metav1.Duration `json:"hibernateAfter,omitempty"`
 
 	// SkipMachinePools allows creating clusterpools where the machinepools are not managed by hive after cluster creation
@@ -80,18 +84,26 @@ type ClusterPoolSpec struct {
 type ClusterPoolClaimLifetime struct {
 	// Default is the default lifetime of the claim when no lifetime is set on the claim itself.
 	// This is a Duration value; see https://pkg.go.dev/time#ParseDuration for accepted formats.
+	// Note: due to discrepancies in validation vs parsing, we use a Pattern instead of `Format=duration`. See
+	// https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+	// https://github.com/kubernetes/apimachinery/issues/131
+	// https://github.com/kubernetes/apiextensions-apiserver/issues/56
 	// +optional
 	// +kubebuilder:validation:Type=string
-	// +kubebuilder:validation:Format=duration
+	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
 	Default *metav1.Duration `json:"default,omitempty"`
 
 	// Maximum is the maximum lifetime of the claim after it is assigned a cluster. If the claim still exists
 	// when the lifetime has elapsed, the claim will be deleted by Hive.
 	// The lifetime of a claim is the mimimum of the lifetimes set by the cluster pool and the claim itself.
 	// This is a Duration value; see https://pkg.go.dev/time#ParseDuration for accepted formats.
+	// Note: due to discrepancies in validation vs parsing, we use a Pattern instead of `Format=duration`. See
+	// https://bugzilla.redhat.com/show_bug.cgi?id=2050332
+	// https://github.com/kubernetes/apimachinery/issues/131
+	// https://github.com/kubernetes/apiextensions-apiserver/issues/56
 	// +optional
 	// +kubebuilder:validation:Type=string
-	// +kubebuilder:validation:Format=duration
+	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
 	Maximum *metav1.Duration `json:"maximum,omitempty"`
 }