Repository: karmada-io/karmada

Issue:
[Flake] Karmada Operator E2E test: PriorityClass configuration testing
#### Which jobs are flaking:
Operator e2e test

#### Which test(s) are flaking:
PriorityClass configuration testing

#### Reason for failure:

Should ignore conflict when updating Karmada resources.

https://github.com/karmada-io/karmada/blob/4e592c1bee6f29a029f46991e251ef7ca6b01929/test/e2e/framework/resource/operator/karmada.go#L74



#### Anything else we need to know:
https://github.com/karmada-io/karmada/actions/runs/18561467239/job/52911926879

```
PriorityClass configuration testing PriorityClass configuration testing [It] Custom priorityClass configuration
/home/runner/work/karmada/karmada/test/e2e/suites/operator/priorityclass_test.go:47

  Captured StdOut/StdErr Output >>
  I1016 12:55:13.697454   45511 karmada.go:39] Waiting for karmada instance operatortest-wq9qn/karmadatest-lxbsg ready
  << Captured StdOut/StdErr Output

  Timeline >>
  STEP: Waiting for karmada instance operatortest-wq9qn/karmadatest-lxbsg ready @ 10/16/25 12:55:13.697
  STEP: Check if default value is system-node-critical @ 10/16/25 12:55:48.756
  STEP: Set priorityClass to system-cluster-critical @ 10/16/25 12:55:48.765
  STEP: Updating Karmada(operatortest-wq9qn/karmadatest-lxbsg) spec @ 10/16/25 12:55:48.78
  [FAILED] in [It] - /home/runner/work/karmada/karmada/test/e2e/framework/resource/operator/karmada.go:75 @ 10/16/25 12:55:48.804
  << Timeline

  [FAILED] Unexpected error:
      <*errors.StatusError | 0xc00001fae0>: 
      Operation cannot be fulfilled on karmadas.operator.karmada.io "karmadatest-lxbsg": the object has been modified; please apply your changes to the latest version and try again
      {
          ErrStatus: {
              TypeMeta: {Kind: "", APIVersion: ""},
              ListMeta: {
                  SelfLink: "",
                  ResourceVersion: "",
                  Continue: "",
                  RemainingItemCount: nil,
              },
              Status: "Failure",
              Message: "Operation cannot be fulfilled on karmadas.operator.karmada.io \"karmadatest-lxbsg\": the object has been modified; please apply your changes to the latest version and try again",
              Reason: "Conflict",
              Details: {
                  Name: "karmadatest-lxbsg",
                  Group: "operator.karmada.io",
                  Kind: "karmadas",
                  UID: "",
                  Causes: nil,
                  RetryAfterSeconds: 0,
              },
              Code: 409,
          },
      }
  occurred
  In [It] at: /home/runner/work/karmada/karmada/test/e2e/framework/resource/operator/karmada.go:75 @ 10/16/25 12:55:48.804
```

Discussion:
@RainbowMango: cc @zhzhuang-zju @zhzhuang-zju: /assign@zhzhuang-zju: This is a common issue where update conflicts are not handled, leading to e2e test failures. I will investigate similar issues in the current codebase and submit a separate PR to address and strengthen these areas.

Solution patch:
diff --git a/charts/karmada-operator/crds/operator.karmada.io_karmadas.yaml b/charts/karmada-operator/crds/operator.karmada.io_karmadas.yaml
index e3894f279..bd1204324 100644
--- a/charts/karmada-operator/crds/operator.karmada.io_karmadas.yaml
+++ b/charts/karmada-operator/crds/operator.karmada.io_karmadas.yaml
@@ -61,32 +61,11 @@ spec:
                           External describes how to connect to an external etcd cluster
                           Local and External are mutually exclusive
                         properties:
-                          caData:
-                            description: |-
-                              CAData is an SSL Certificate Authority file used to secure etcd communication.
-                              Required if using a TLS connection.
-                              Deprecated: This field is deprecated and will be removed in a future version. Use SecretRef for providing client connection credentials.
-                            format: byte
-                            type: string
-                          certData:
-                            description: |-
-                              CertData is an SSL certification file used to secure etcd communication.
-                              Required if using a TLS connection.
-                              Deprecated: This field is deprecated and will be removed in a future version. Use SecretRef for providing client connection credentials.
-                            format: byte
-                            type: string
                           endpoints:
                             description: Endpoints of etcd members. Required for ExternalEtcd.
                             items:
                               type: string
                             type: array
-                          keyData:
-                            description: |-
-                              KeyData is an SSL key file used to secure etcd communication.
-                              Required if using a TLS connection.
-                              Deprecated: This field is deprecated and will be removed in a future version. Use SecretRef for providing client connection credentials.
-                            format: byte
-                            type: string
                           secretRef:
                             description: |-
                               SecretRef references a Kubernetes secret containing the etcd connection credentials.
diff --git a/hack/cherry_pick_pull.sh b/hack/cherry_pick_pull.sh
index 39810ca69..cdd75700f 100755
--- a/hack/cherry_pick_pull.sh
+++ b/hack/cherry_pick_pull.sh
@@ -134,6 +134,7 @@ function return_to_kansas {
 trap return_to_kansas EXIT
 
 SUBJECTS=()
+RELEASE_NOTES=()
 function make-a-pr() {
   local rel
   rel="$(basename "${BRANCH}")"
@@ -142,12 +143,17 @@ function make-a-pr() {
 
   local numandtitle
   numandtitle=$(printf '%s\n' "${SUBJECTS[@]}")
+  local release_notes
+  if ((${#RELEASE_NOTES[@]} > 0)); then
+    release_notes=$(printf '%s\n' "${RELEASE_NOTES[@]}")
+  fi
   prtext=$(
     cat <<EOF
 Cherry pick of ${PULLSUBJ} on ${rel}.
 ${numandtitle}
 For details on the cherry pick process, see the [cherry pick requests](https://karmada.io/docs/contributor/cherry-picks) page.
 \`\`\`release-note
+${release_notes}
 \`\`\`
 EOF
   )
@@ -196,6 +202,14 @@ for pull in "${PULLS[@]}"; do
   subject=$(grep -m 1 "^Subject" "/tmp/${pull}.patch" | sed -e 's/Subject: \[PATCH//g' | sed 's/.*] //')
   SUBJECTS+=("#${pull}: ${subject}")
 
+  # get release note
+  echo "+++ Getting release note from PR ${pull}"
+  pr_body=$(gh pr view "${pull}" --json body --repo "${MAIN_REPO_ORG}/${MAIN_REPO_NAME}" -q '.body')
+  release_note=$(echo "${pr_body}" | sed -n '/```release-note/,/```/p' | sed '/^```/d' | awk 'NF')
+  if [[ -n "${release_note}" && "${release_note}" != "NONE" ]]; then
+    RELEASE_NOTES+=("${release_note}")
+  fi
+
   # remove the patch file from /tmp
   rm -f "/tmp/${pull}.patch"
 done
diff --git a/operator/config/crds/operator.karmada.io_karmadas.yaml b/operator/config/crds/operator.karmada.io_karmadas.yaml
index e3894f279..bd1204324 100644
--- a/operator/config/crds/operator.karmada.io_karmadas.yaml
+++ b/operator/config/crds/operator.karmada.io_karmadas.yaml
@@ -61,32 +61,11 @@ spec:
                           External describes how to connect to an external etcd cluster
                           Local and External are mutually exclusive
                         properties:
-                          caData:
-                            description: |-
-                              CAData is an SSL Certificate Authority file used to secure etcd communication.
-                              Required if using a TLS connection.
-                              Deprecated: This field is deprecated and will be removed in a future version. Use SecretRef for providing client connection credentials.
-                            format: byte
-                            type: string
-                          certData:
-                            description: |-
-                              CertData is an SSL certification file used to secure etcd communication.
-                              Required if using a TLS connection.
-                              Deprecated: This field is deprecated and will be removed in a future version. Use SecretRef for providing client connection credentials.
-                            format: byte
-                            type: string
                           endpoints:
                             description: Endpoints of etcd members. Required for ExternalEtcd.
                             items:
                               type: string
                             type: array
-                          keyData:
-                            description: |-
-                              KeyData is an SSL key file used to secure etcd communication.
-                              Required if using a TLS connection.
-                              Deprecated: This field is deprecated and will be removed in a future version. Use SecretRef for providing client connection credentials.
-                            format: byte
-                            type: string
                           secretRef:
                             description: |-
                               SecretRef references a Kubernetes secret containing the etcd connection credentials.
diff --git a/operator/pkg/apis/operator/v1alpha1/type.go b/operator/pkg/apis/operator/v1alpha1/type.go
index f184a4281..e42d4c2ed 100644
--- a/operator/pkg/apis/operator/v1alpha1/type.go
+++ b/operator/pkg/apis/operator/v1alpha1/type.go
@@ -291,21 +291,6 @@ type ExternalEtcd struct {
 	// +required
 	Endpoints []string `json:"endpoints"`
 
-	// CAData is an SSL Certificate Authority file used to secure etcd communication.
-	// Required if using a TLS connection.
-	// Deprecated: This field is deprecated and will be removed in a future version. Use SecretRef for providing client connection credentials.
-	CAData []byte `json:"caData,omitempty"`
-
-	// CertData is an SSL certification file used to secure etcd communication.
-	// Required if using a TLS connection.
-	// Deprecated: This field is deprecated and will be removed in a future version. Use SecretRef for providing client connection credentials.
-	CertData []byte `json:"certData,omitempty"`
-
-	// KeyData is an SSL key file used to secure etcd communication.
-	// Required if using a TLS connection.
-	// Deprecated: This field is deprecated and will be removed in a future version. Use SecretRef for providing client connection credentials.
-	KeyData []byte `json:"keyData,omitempty"`
-
 	// SecretRef references a Kubernetes secret containing the etcd connection credentials.
 	// The secret must contain the following data keys:
 	// ca.crt: The Certificate Authority (CA) certificate data.
diff --git a/operator/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go b/operator/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go
index ca15fc1c9..e85b926f0 100644
--- a/operator/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go
+++ b/operator/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go
@@ -166,21 +166,6 @@ func (in *ExternalEtcd) DeepCopyInto(out *ExternalEtcd) {
 		*out = make([]string, len(*in))
 		copy(*out, *in)
 	}
-	if in.CAData != nil {
-		in, out := &in.CAData, &out.CAData
-		*out = make([]byte, len(*in))
-		copy(*out, *in)
-	}
-	if in.CertData != nil {
-		in, out := &in.CertData, &out.CertData
-		*out = make([]byte, len(*in))
-		copy(*out, *in)
-	}
-	if in.KeyData != nil {
-		in, out := &in.KeyData, &out.KeyData
-		*out = make([]byte, len(*in))
-		copy(*out, *in)
-	}
 	out.SecretRef = in.SecretRef
 	return
 }
diff --git a/pkg/estimator/client/accurate.go b/pkg/estimator/client/accurate.go
index d82417302..7720f3ab4 100644
--- a/pkg/estimator/client/accurate.go
+++ b/pkg/estimator/client/accurate.go
@@ -68,9 +68,7 @@ func (se *SchedulerEstimator) MaxAvailableReplicas(
 }
 
 // MaxAvailableComponentSets returns the maximum number of complete multi-component sets (in terms of replicas) that each cluster can host.
-func (se *SchedulerEstimator) MaxAvailableComponentSets(
-	_ context.Context,
-	_ *ComponentSetEstimationRequest) ([]ComponentSetEstimationResponse, error) {
+func (se *SchedulerEstimator) MaxAvailableComponentSets(_ context.Context, _ ComponentSetEstimationRequest) ([]ComponentSetEstimationResponse, error) {
 	// Dummy implementation: return nothing for now
 	// TODO: Implement as part of #6734
 	return nil, nil
diff --git a/pkg/estimator/client/general.go b/pkg/estimator/client/general.go
index 3905e6b30..bec47cfd2 100644
--- a/pkg/estimator/client/general.go
+++ b/pkg/estimator/client/general.go
@@ -94,7 +94,7 @@ func (ge *GeneralEstimator) maxAvailableReplicas(cluster *clusterv1alpha1.Cluste
 }
 
 // MaxAvailableComponentSets (generic estimator) – resourceSummary only.
-func (ge *GeneralEstimator) MaxAvailableComponentSets(_ context.Context, req *ComponentSetEstimationRequest) ([]ComponentSetEstimationResponse, error) {
+func (ge *GeneralEstimator) MaxAvailableComponentSets(_ context.Context, req ComponentSetEstimationRequest) ([]ComponentSetEstimationResponse, error) {
 	responses := make([]ComponentSetEstimationResponse, len(req.Clusters))
 	for i, cluster := range req.Clusters {
 		maxComponentSets := ge.maxAvailableComponentSets(cluster, req.Components)
@@ -103,7 +103,7 @@ func (ge *GeneralEstimator) MaxAvailableComponentSets(_ context.Context, req *Co
 	return responses, nil
 }
 
-func (ge *GeneralEstimator) maxAvailableComponentSets(cluster *clusterv1alpha1.Cluster, components []*workv1alpha2.Component) int32 {
+func (ge *GeneralEstimator) maxAvailableComponentSets(cluster *clusterv1alpha1.Cluster, components []workv1alpha2.Component) int32 {
 	resourceSummary := cluster.Status.ResourceSummary.DeepCopy()
 	if resourceSummary == nil {
 		return 0
@@ -163,14 +163,14 @@ func (ge *GeneralEstimator) maxAvailableComponentSets(cluster *clusterv1alpha1.C
 // getMaximumSetsBasedOnResourceModels is a placeholder for future implementation.
 // It should refine the maximum sets based on cluster resource models, similar
 // to getMaximumReplicasBasedOnResourceModels but adapted to full component sets.
-func getMaximumSetsBasedOnResourceModels(_ *clusterv1alpha1.Cluster, _ []*workv1alpha2.Component) (int64, error) {
+func getMaximumSetsBasedOnResourceModels(_ *clusterv1alpha1.Cluster, _ []workv1alpha2.Component) (int64, error) {
 	// TODO: implement logic based on cluster.Spec.ResourceModels
 	// For now, just return MaxInt64 so it never reduces the upper bound.
 	return math.MaxInt64, nil
 }
 
 // podsInSet computes the total number of pods in the CRD
-func podsInSet(components []*workv1alpha2.Component) int64 {
+func podsInSet(components []workv1alpha2.Component) int64 {
 	var sum int64
 	for _, c := range components {
 		sum += int64(c.Replicas)
@@ -179,7 +179,7 @@ func podsInSet(components []*workv1alpha2.Component) int64 {
 }
 
 // perSetRequirement computes the aggregate resource(such as CPU, Memory, GPU, etc) demand of one set of components.
-func perSetRequirement(components []*workv1alpha2.Component) map[corev1.ResourceName]int64 {
+func perSetRequirement(components []workv1alpha2.Component) map[corev1.ResourceName]int64 {
 	resourceRequirements := map[corev1.ResourceName]int64{}
 	for _, c := range components {
 		if c.ReplicaRequirements == nil || c.ReplicaRequirements.ResourceRequest == nil {
diff --git a/pkg/estimator/client/interface.go b/pkg/estimator/client/interface.go
index 0ffb968f1..62b24061c 100644
--- a/pkg/estimator/client/interface.go
+++ b/pkg/estimator/client/interface.go
@@ -40,7 +40,7 @@ type ReplicaEstimator interface {
 	// MaxAvailableReplicas returns the maximum number of replicas of a single-component workload that each cluster can host.
 	MaxAvailableReplicas(ctx context.Context, clusters []*clusterv1alpha1.Cluster, replicaRequirements *workv1alpha2.ReplicaRequirements) ([]workv1alpha2.TargetCluster, error)
 	// MaxAvailableComponentSets returns the maximum number of complete multi-component sets (in terms of replicas) that each cluster can host.
-	MaxAvailableComponentSets(ctx context.Context, req *ComponentSetEstimationRequest) ([]ComponentSetEstimationResponse, error)
+	MaxAvailableComponentSets(ctx context.Context, req ComponentSetEstimationRequest) ([]ComponentSetEstimationResponse, error)
 }
 
 // ComponentSetEstimationRequest carries input parameters for estimating multi-component set availability per cluster.
@@ -49,7 +49,7 @@ type ComponentSetEstimationRequest struct {
 	// Clusters represents a list of feasible clusters to estimate against.
 	Clusters []*clusterv1alpha1.Cluster
 	// Components are the components that form a multi-component workload.
-	Components []*workv1alpha2.Component
+	Components []workv1alpha2.Component
 	// Namespace is the namespace of the workload being estimated.
 	// It is used by the accurate estimator to check the quota configurations
 	// in the target member cluster. This field is required for quota-aware estimation.



Test patch:
diff --git a/pkg/estimator/client/general_test.go b/pkg/estimator/client/general_test.go
index b0b5e91a3..6ab1bbb71 100644
--- a/pkg/estimator/client/general_test.go
+++ b/pkg/estimator/client/general_test.go
@@ -805,7 +805,7 @@ func TestGetMaxAvailableComponentSetsGeneral(t *testing.T) {
 	tests := []struct {
 		name       string
 		cluster    *clusterv1alpha1.Cluster
-		components []*workv1alpha2.Component
+		components []workv1alpha2.Component
 		expected   int32
 	}{
 		{
@@ -862,7 +862,7 @@ func TestGetMaxAvailableComponentSetsGeneral(t *testing.T) {
 					},
 				},
 			},
-			components: []*workv1alpha2.Component{
+			components: []workv1alpha2.Component{
 				{
 					Name:     "jobmanager",
 					Replicas: 1,
@@ -902,7 +902,7 @@ func TestGetMaxAvailableComponentSetsGeneral(t *testing.T) {
 					},
 				},
 			},
-			components: []*workv1alpha2.Component{
+			components: []workv1alpha2.Component{
 				{
 					Name:     "jobmanager",
 					Replicas: 1,
@@ -943,7 +943,7 @@ func TestGetMaxAvailableComponentSetsGeneral(t *testing.T) {
 					},
 				},
 			},
-			components: []*workv1alpha2.Component{
+			components: []workv1alpha2.Component{
 				{
 					Name:     "small-component",
 					Replicas: 3,
@@ -977,7 +977,7 @@ func TestGetMaxAvailableComponentSetsGeneral(t *testing.T) {
 					},
 				},
 			},
-			components: []*workv1alpha2.Component{
+			components: []workv1alpha2.Component{
 				{
 					Name:     "gpu-worker",
 					Replicas: 2,
diff --git a/test/e2e/framework/clusterpropagationpolicy.go b/test/e2e/framework/clusterpropagationpolicy.go
index 74a9e3ece..d9bb70860 100644
--- a/test/e2e/framework/clusterpropagationpolicy.go
+++ b/test/e2e/framework/clusterpropagationpolicy.go
@@ -26,6 +26,7 @@ import (
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/client-go/util/retry"
 
 	policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
 	karmada "github.com/karmada-io/karmada/pkg/generated/clientset/versioned"
@@ -61,23 +62,33 @@ func PatchClusterPropagationPolicy(client karmada.Interface, name string, patch
 // UpdateClusterPropagationPolicyWithSpec update PropagationSpec with karmada client.
 func UpdateClusterPropagationPolicyWithSpec(client karmada.Interface, name string, policySpec policyv1alpha1.PropagationSpec) {
 	ginkgo.By(fmt.Sprintf("Updating ClusterPropagationPolicy(%s) spec", name), func() {
-		newPolicy, err := client.PolicyV1alpha1().ClusterPropagationPolicies().Get(context.TODO(), name, metav1.GetOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+		err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
+			newPolicy, err := client.PolicyV1alpha1().ClusterPropagationPolicies().Get(context.TODO(), name, metav1.GetOptions{})
+			if err != nil {
+				return err
+			}
 
-		newPolicy.Spec = policySpec
-		_, err = client.PolicyV1alpha1().ClusterPropagationPolicies().Update(context.TODO(), newPolicy, metav1.UpdateOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+			newPolicy.Spec = policySpec
+			_, err = client.PolicyV1alpha1().ClusterPropagationPolicies().Update(context.TODO(), newPolicy, metav1.UpdateOptions{})
+			return err
+		})
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	})
 }
 
 // UpdateClusterPropagationPolicy update ClusterPropagationPolicy resourceSelectors with karmada client.
 func UpdateClusterPropagationPolicy(client karmada.Interface, name string, resourceSelectors []policyv1alpha1.ResourceSelector) {
 	ginkgo.By(fmt.Sprintf("Updating ClusterPropagationPolicy(%s)", name), func() {
-		newPolicy, err := client.PolicyV1alpha1().ClusterPropagationPolicies().Get(context.TODO(), name, metav1.GetOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+		err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
+			newPolicy, err := client.PolicyV1alpha1().ClusterPropagationPolicies().Get(context.TODO(), name, metav1.GetOptions{})
+			if err != nil {
+				return err
+			}
 
-		newPolicy.Spec.ResourceSelectors = resourceSelectors
-		_, err = client.PolicyV1alpha1().ClusterPropagationPolicies().Update(context.TODO(), newPolicy, metav1.UpdateOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+			newPolicy.Spec.ResourceSelectors = resourceSelectors
+			_, err = client.PolicyV1alpha1().ClusterPropagationPolicies().Update(context.TODO(), newPolicy, metav1.UpdateOptions{})
+			return err
+		})
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	})
 }
diff --git a/test/e2e/framework/cronfederatedhpa.go b/test/e2e/framework/cronfederatedhpa.go
index 6516c9218..03849b108 100644
--- a/test/e2e/framework/cronfederatedhpa.go
+++ b/test/e2e/framework/cronfederatedhpa.go
@@ -23,6 +23,7 @@ import (
 	"github.com/onsi/ginkgo/v2"
 	"github.com/onsi/gomega"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/client-go/util/retry"
 
 	autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1"
 	karmada "github.com/karmada-io/karmada/pkg/generated/clientset/versioned"
@@ -47,11 +48,16 @@ func RemoveCronFederatedHPA(client karmada.Interface, namespace, name string) {
 // UpdateCronFederatedHPAWithRule update CronFederatedHPA with karmada client.
 func UpdateCronFederatedHPAWithRule(client karmada.Interface, namespace, name string, rule []autoscalingv1alpha1.CronFederatedHPARule) {
 	ginkgo.By(fmt.Sprintf("Updating CronFederatedHPA(%s/%s)", namespace, name), func() {
-		newCronFederatedHPA, err := client.AutoscalingV1alpha1().CronFederatedHPAs(namespace).Get(context.TODO(), name, metav1.GetOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
-
-		newCronFederatedHPA.Spec.Rules = rule
-		_, err = client.AutoscalingV1alpha1().CronFederatedHPAs(namespace).Update(context.TODO(), newCronFederatedHPA, metav1.UpdateOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+		err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
+			newCronFederatedHPA, err := client.AutoscalingV1alpha1().CronFederatedHPAs(namespace).Get(context.TODO(), name, metav1.GetOptions{})
+			if err != nil {
+				return err
+			}
+
+			newCronFederatedHPA.Spec.Rules = rule
+			_, err = client.AutoscalingV1alpha1().CronFederatedHPAs(namespace).Update(context.TODO(), newCronFederatedHPA, metav1.UpdateOptions{})
+			return err
+		})
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	})
 }
diff --git a/test/e2e/framework/hpa.go b/test/e2e/framework/hpa.go
index 71834d2a8..1b0786097 100644
--- a/test/e2e/framework/hpa.go
+++ b/test/e2e/framework/hpa.go
@@ -25,6 +25,7 @@ import (
 	autoscalingv2 "k8s.io/api/autoscaling/v2"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/util/retry"
 )
 
 // CreateHPA create HPA.
@@ -46,11 +47,16 @@ func RemoveHPA(client kubernetes.Interface, namespace, name string) {
 // UpdateHPAWithMinReplicas update HPA with replicas.
 func UpdateHPAWithMinReplicas(client kubernetes.Interface, namespace, name string, minReplicas int32) {
 	ginkgo.By(fmt.Sprintf("Updating HPA(%s/%s)", namespace, name), func() {
-		newHPA, err := client.AutoscalingV2().HorizontalPodAutoscalers(namespace).Get(context.TODO(), name, metav1.GetOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
-
-		newHPA.Spec.MinReplicas = &minReplicas
-		_, err = client.AutoscalingV2().HorizontalPodAutoscalers(namespace).Update(context.TODO(), newHPA, metav1.UpdateOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+		err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
+			newHPA, err := client.AutoscalingV2().HorizontalPodAutoscalers(namespace).Get(context.TODO(), name, metav1.GetOptions{})
+			if err != nil {
+				return err
+			}
+
+			newHPA.Spec.MinReplicas = &minReplicas
+			_, err = client.AutoscalingV2().HorizontalPodAutoscalers(namespace).Update(context.TODO(), newHPA, metav1.UpdateOptions{})
+			return err
+		})
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	})
 }
diff --git a/test/e2e/framework/propagationpolicy.go b/test/e2e/framework/propagationpolicy.go
index 48208d318..60866c9db 100644
--- a/test/e2e/framework/propagationpolicy.go
+++ b/test/e2e/framework/propagationpolicy.go
@@ -26,6 +26,7 @@ import (
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/client-go/util/retry"
 	"k8s.io/klog/v2"
 
 	policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
@@ -78,12 +79,17 @@ func PatchPropagationPolicy(client karmada.Interface, namespace, name string, pa
 // UpdatePropagationPolicyWithSpec update PropagationSpec with karmada client.
 func UpdatePropagationPolicyWithSpec(client karmada.Interface, namespace, name string, policySpec policyv1alpha1.PropagationSpec) {
 	ginkgo.By(fmt.Sprintf("Updating PropagationPolicy(%s/%s) spec", namespace, name), func() {
-		newPolicy, err := client.PolicyV1alpha1().PropagationPolicies(namespace).Get(context.TODO(), name, metav1.GetOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+		err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
+			newPolicy, err := client.PolicyV1alpha1().PropagationPolicies(namespace).Get(context.TODO(), name, metav1.GetOptions{})
+			if err != nil {
+				return err
+			}
 
-		newPolicy.Spec = policySpec
-		_, err = client.PolicyV1alpha1().PropagationPolicies(newPolicy.Namespace).Update(context.TODO(), newPolicy, metav1.UpdateOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+			newPolicy.Spec = policySpec
+			_, err = client.PolicyV1alpha1().PropagationPolicies(newPolicy.Namespace).Update(context.TODO(), newPolicy, metav1.UpdateOptions{})
+			return err
+		})
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	})
 }
 
diff --git a/test/e2e/framework/resource/operator/karmada.go b/test/e2e/framework/resource/operator/karmada.go
index d0ef1551f..821083c55 100644
--- a/test/e2e/framework/resource/operator/karmada.go
+++ b/test/e2e/framework/resource/operator/karmada.go
@@ -25,6 +25,7 @@ import (
 	"github.com/onsi/gomega"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/client-go/util/retry"
 	"k8s.io/klog/v2"
 
 	operatorv1alpha1 "github.com/karmada-io/karmada/operator/pkg/apis/operator/v1alpha1"
@@ -67,12 +68,17 @@ func CreateKarmadaInstance(operatorClient operator.Interface, karmada *operatorv
 // UpdateKarmadaInstanceWithSpec updates karmada instance with spec.
 func UpdateKarmadaInstanceWithSpec(client operator.Interface, namespace, name string, karmadaSpec operatorv1alpha1.KarmadaSpec) {
 	ginkgo.By(fmt.Sprintf("Updating Karmada(%s/%s) spec", namespace, name), func() {
-		karmada, err := client.OperatorV1alpha1().Karmadas(namespace).Get(context.TODO(), name, metav1.GetOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+		err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
+			karmada, err := client.OperatorV1alpha1().Karmadas(namespace).Get(context.TODO(), name, metav1.GetOptions{})
+			if err != nil {
+				return err
+			}
 
-		karmada.Spec = karmadaSpec
-		_, err = client.OperatorV1alpha1().Karmadas(namespace).Update(context.TODO(), karmada, metav1.UpdateOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+			karmada.Spec = karmadaSpec
+			_, err = client.OperatorV1alpha1().Karmadas(namespace).Update(context.TODO(), karmada, metav1.UpdateOptions{})
+			return err
+		})
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	})
 }
 
diff --git a/test/e2e/framework/resourceregistry.go b/test/e2e/framework/resourceregistry.go
index 3868be9f9..b822869cf 100644
--- a/test/e2e/framework/resourceregistry.go
+++ b/test/e2e/framework/resourceregistry.go
@@ -23,6 +23,7 @@ import (
 	"github.com/onsi/ginkgo/v2"
 	"github.com/onsi/gomega"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/client-go/util/retry"
 
 	searchv1alpha1 "github.com/karmada-io/karmada/pkg/apis/search/v1alpha1"
 	karmada "github.com/karmada-io/karmada/pkg/generated/clientset/versioned"
@@ -44,10 +45,19 @@ func RemoveResourceRegistry(client karmada.Interface, name string) {
 	})
 }
 
-// UpdateResourceRegistry patch ResourceRegistry with karmada client.
-func UpdateResourceRegistry(client karmada.Interface, rr *searchv1alpha1.ResourceRegistry) {
+// UpdateResourceRegistryWithSpec patch ResourceRegistry with karmada client.
+func UpdateResourceRegistryWithSpec(client karmada.Interface, rr *searchv1alpha1.ResourceRegistry) {
 	ginkgo.By(fmt.Sprintf("Update ResourceRegistry(%s)", rr.Name), func() {
-		_, err := client.SearchV1alpha1().ResourceRegistries().Update(context.TODO(), rr, metav1.UpdateOptions{})
-		gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+		err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
+			latestRR, err := client.SearchV1alpha1().ResourceRegistries().Get(context.TODO(), rr.Name, metav1.GetOptions{})
+			if err != nil {
+				return err
+			}
+
+			latestRR.Spec = rr.Spec
+			_, err = client.SearchV1alpha1().ResourceRegistries().Update(context.TODO(), latestRR, metav1.UpdateOptions{})
+			return err
+		})
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	})
 }
diff --git a/test/e2e/suites/base/search_test.go b/test/e2e/suites/base/search_test.go
index aeb363192..a441b623d 100644
--- a/test/e2e/suites/base/search_test.go
+++ b/test/e2e/suites/base/search_test.go
@@ -326,7 +326,7 @@ var _ = ginkgo.Describe("[karmada-search] karmada search testing", ginkgo.Ordere
 					Kind:       "ClusterRoleBinding",
 				},
 			}
-			framework.UpdateResourceRegistry(karmadaClient, rr)
+			framework.UpdateResourceRegistryWithSpec(karmadaClient, rr)
 			searchObject(pathAllClusterRoleBindings, existsClusterRoleBindingName, true)
 		})
 	})