Repository: etcd-io/etcd

Issue:
Bug in robustness test history patching
### Bug report criteria

- [ ] This bug report is not security related, security issues should be disclosed privately via [etcd maintainers](mailto:etcd-maintainers@googlegroups.com).
- [ ] This is not a support request or question, support requests or questions should be raised in the etcd [discussion forums](https://github.com/etcd-io/etcd/discussions).
- [ ] You have read the etcd [bug reporting guidelines](https://github.com/etcd-io/etcd/blob/main/Documentation/contributor-guide/reporting_bugs.md).
- [ ] Existing open issues along with etcd [frequently asked questions](https://etcd.io/docs/latest/faq) have been checked and this is not a duplicate.

### What happened?

Test https://prow.k8s.io/view/gs/kubernetes-ci-logs/logs/ci-etcd-robustness-release35-amd64/1883794260398968832 failed with panic `panic: interface conversion: interface {} is nil, not model.EtcdRequest`

Issue is reproducible locally from the report showing failed linearizaiton.

However, when I disabled history patching I got linearization success, implying that there is a bug in history patching.

### What did you expect to happen?

Robustness test validation should not panic

### How can we reproduce it (as minimally and precisely as possible)?

Follow instructions https://github.com/etcd-io/etcd/tree/main/tests/robustness#re-evaluate-existing-report on artifact from https://prow.k8s.io/view/gs/kubernetes-ci-logs/logs/ci-etcd-robustness-release35-amd64/1883794260398968832

### Anything else we need to know?

_No response_

### Etcd version (please run commands below)

<details>

```console
$ etcd --version
# paste output here

$ etcdctl version
# paste output here
```

</details>


### Etcd configuration (command line flags or environment variables)

<details>

# paste your configuration here

</details>


### Etcd debug information (please run commands below, feel free to obfuscate the IP address or FQDN in the output)

<details>

```console
$ etcdctl member list -w table
# paste output here

$ etcdctl --endpoints=<member list> endpoint status -w table
# paste output here
```

</details>


### Relevant log output

```Shell

```

Hints from issue comments:
@joshuazh-x: The panic is caused by a patched `porcupine.Operation` whose invocation timestamp is behind its response timestamp. This breaks the causality assumption when building linearization visual. 

The root cause comes from adjusting put return time when there are multiple wal entries having same put requests (same key and value). The put request for this specific case is `Put("compact_rev_key", "1055")`.  When iterating persisted requests in reverse order, the last occurrence of such put request will adjust its return time using the earliest observed client return time which shall actually belong to its first occurrence. This may twist following calculation and make some request's return time too earlier to before its invocation time.

https://github.com/etcd-io/etcd/blob/ad3301099ab2edc09cfc79754c4063fd658cd13f/tests/robustness/validate/patch_history.go#L207-L229@serathius: Makes sense, thanks for looking into @joshuazh-x !

Solution patch:
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 676a5a7da..b095950ac 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -40,7 +40,7 @@ jobs:
         uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
       # Initializes the CodeQL tools for scanning.
       - name: Initialize CodeQL
-        uses: github/codeql-action/init@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
+        uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
         with:
           # If you wish to specify custom queries, you can do so here or in a config file.
           # By default, queries listed here will override any specified in a config file.
@@ -50,6 +50,6 @@ jobs:
       # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
       # If this step fails, then you should remove it and run the build manually (see below)
       - name: Autobuild
-        uses: github/codeql-action/autobuild@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
+        uses: github/codeql-action/autobuild@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
       - name: Perform CodeQL Analysis
-        uses: github/codeql-action/analyze@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
+        uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
diff --git a/.github/workflows/grpcproxy.yaml b/.github/workflows/grpcproxy.yaml
deleted file mode 100644
index 93e6a20bd..000000000
--- a/.github/workflows/grpcproxy.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
----
-name: grpcProxy-tests
-on: [push, pull_request]
-permissions: read-all
-jobs:
-  test:
-    runs-on: ubuntu-latest
-    strategy:
-      fail-fast: false
-      matrix:
-        target:
-          - linux-amd64-grpcproxy-integration
-          - linux-amd64-grpcproxy-e2e
-    steps:
-      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
-      - id: goversion
-        run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
-      - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
-        with:
-          go-version: ${{ steps.goversion.outputs.goversion }}
-      - env:
-          TARGET: ${{ matrix.target }}
-        run: |
-          set -euo pipefail
-
-          echo "${TARGET}"
-          case "${TARGET}" in
-            linux-amd64-grpcproxy-integration)
-              GOOS=linux GOARCH=amd64 CPU=4 make test-grpcproxy-integration
-              ;;
-            linux-amd64-grpcproxy-e2e)
-              GOOS=linux GOARCH=amd64 CPU=4 make test-grpcproxy-e2e
-              ;;
-            *)
-              echo "Failed to find target"
-              exit 1
-              ;;
-          esac
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
deleted file mode 100644
index 2e1230951..000000000
--- a/.github/workflows/release.yaml
+++ /dev/null
@@ -1,77 +0,0 @@
----
-name: Release
-on: [push, pull_request]
-permissions: read-all
-jobs:
-  main:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
-      - id: goversion
-        run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
-      - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
-        with:
-          go-version: ${{ steps.goversion.outputs.goversion }}
-      - name: release
-        run: |
-          set -euo pipefail
-
-          git config --global user.email "github-action@etcd.io"
-          git config --global user.name "Github Action"
-          gpg --batch --gen-key <<EOF
-          %no-protection
-          Key-Type: 1
-          Key-Length: 2048
-          Subkey-Type: 1
-          Subkey-Length: 2048
-          Name-Real: Github Action
-          Name-Email: github-action@etcd.io
-          Expire-Date: 0
-          EOF
-          DRY_RUN=true ./scripts/release.sh --no-upload --no-docker-push --no-gh-release --in-place 3.6.99
-      - name: test-image
-        run: |
-          VERSION=3.6.99 ./scripts/test_images.sh
-      - name: save-image
-        run: |
-          docker image save -o /tmp/etcd-img.tar gcr.io/etcd-development/etcd
-      - name: upload-image
-        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
-        with:
-          name: etcd-img
-          path: /tmp/etcd-img.tar
-          retention-days: 1
-  trivy-scan:
-    needs: main
-    strategy:
-      fail-fast: false
-      matrix:
-        platforms: [amd64, arm64, ppc64le, s390x]
-    permissions:
-      security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
-    runs-on: ubuntu-latest
-    steps:
-      - name: get-image
-        uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
-        with:
-          name: etcd-img
-          path: /tmp
-      - name: load-image
-        run: |
-          docker load < /tmp/etcd-img.tar
-      - name: trivy-scan
-        uses: aquasecurity/trivy-action@18f2510ee396bbf400402947b394f2dd8c87dbb0 # v0.29.0
-        with:
-          image-ref: 'gcr.io/etcd-development/etcd:v3.6.99-${{ matrix.platforms }}'
-          severity: 'CRITICAL,HIGH'
-          format: 'sarif'
-          output: 'trivy-results-${{ matrix.platforms }}.sarif'
-        env:
-          # Use AWS' ECR mirror for the trivy-db image, as GitHub's Container
-          # Registry is returning a TOOMANYREQUESTS error.
-          # Ref: https://github.com/aquasecurity/trivy-action/issues/389
-          TRIVY_DB_REPOSITORY: 'public.ecr.aws/aquasecurity/trivy-db:2'
-      - name: upload scan results
-        uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
-        with:
-          sarif_file: 'trivy-results-${{ matrix.platforms }}.sarif'
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index b0ac7e1e1..8e5ee16eb 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -28,7 +28,7 @@ jobs:
           persist-credentials: false
 
       - name: "Run analysis"
-        uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
+        uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
         with:
           results_file: results.sarif
           results_format: sarif
@@ -42,7 +42,7 @@ jobs:
       # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
       # format to the repository Actions tab.
       - name: "Upload artifact"
-        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
+        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
         with:
           name: SARIF file
           path: results.sarif
@@ -50,6 +50,6 @@ jobs:
 
       # Upload the results to GitHub's code scanning dashboard.
       - name: "Upload to code-scanning"
-        uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
+        uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
         with:
           sarif_file: results.sarif
diff --git a/.github/workflows/verify-released-assets.yaml b/.github/workflows/verify-released-assets.yaml
new file mode 100644
index 000000000..3db5e98c8
--- /dev/null
+++ b/.github/workflows/verify-released-assets.yaml
@@ -0,0 +1,44 @@
+---
+name: Verify released binary assets
+permissions: read-all
+
+on:
+  release:
+    types: [published]
+
+jobs:
+  verify-assets:
+    name: Verify released binary assets
+    runs-on: ubuntu-latest
+    steps:
+      - name: Verify binary assets
+        env:
+          GH_TOKEN: ${{ github.token }}
+          RELEASE: ${{ github.event.release.tag_name }}
+          REPOSITORY: ${{ github.repository }}
+        run: |
+          mkdir github-assets
+          pushd github-assets
+          gh --repo "${REPOSITORY}" release download "${RELEASE}"
+
+          test_assets() {
+            if [ "$(wc -l <SHA256SUMS)" != "$(find . -name 'etcd-*' | wc -l)" ]; then
+              echo "::error:: Invalid number of assets"
+              exit 1
+            fi
+            sha256sum -c SHA256SUMS
+          }
+          test_assets
+          popd
+
+          mkdir google-assets
+          for file in github-assets/*; do
+            file=$(basename "${file}")
+            echo "Downloading ${file} from Google..."
+            curl "https://storage.googleapis.com/etcd/${RELEASE}/${file}" \
+            --fail \
+            -o "google-assets/${file}"
+          done
+          pushd google-assets
+
+          test_assets
diff --git a/.go-version b/.go-version
index d8c40e539..f9e8384bb 100644
--- a/.go-version
+++ b/.go-version
@@ -1 +1 @@
-1.23.6
+1.24.1
diff --git a/CHANGELOG/CHANGELOG-3.4.md b/CHANGELOG/CHANGELOG-3.4.md
index dbf3adbc2..c5c52c8f6 100644
--- a/CHANGELOG/CHANGELOG-3.4.md
+++ b/CHANGELOG/CHANGELOG-3.4.md
@@ -4,7 +4,15 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
 
 <hr>
 
-## v3.4.36 (TBC)
+## v3.4.37 (TBC)
+
+### Dependencies
+- Bump [golang.org/x/net to v0.36.0 to address CVE-2025-22870](https://github.com/etcd-io/etcd/pull/19529).
+- Compile binaries using [go 1.23.7](https://github.com/etcd-io/etcd/pull/19533)
+
+<hr>
+
+## v3.4.36 (2025-02-25)
 
 ### etcd server
 - [Avoid deadlock in etcd.Close when stopping during bootstrapping](https://github.com/etcd-io/etcd/pull/19166)
@@ -15,7 +23,8 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
 
 ### Dependencies
 - Compile binaries using [go 1.23.6](https://github.com/etcd-io/etcd/pull/19429)
-- Bump [golang.org/x/crypto to 0.32.0 to address CVE-2024-45337 and golang.org/x/net to 0.34.0 to address CVE-2024-45338](https://github.com/etcd-io/etcd/pull/19197).
+- Bump golang.org/x/crypto to v0.35.0 to address [CVE-2024-45337](https://github.com/etcd-io/etcd/pull/19197) and [CVE-2025-22869](https://github.com/etcd-io/etcd/pull/19477).
+- Bump golang.org/x/net to v0.34.0 to address [CVE-2024-45338](https://github.com/etcd-io/etcd/pull/19197).
 
 <hr>
 
diff --git a/CHANGELOG/CHANGELOG-3.5.md b/CHANGELOG/CHANGELOG-3.5.md
index 44041890f..c3cc6b8d6 100644
--- a/CHANGELOG/CHANGELOG-3.5.md
+++ b/CHANGELOG/CHANGELOG-3.5.md
@@ -3,7 +3,11 @@
 Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.4.md).
 <hr>
 
-## v3.5.19 (TBC)
+## v3.5.20 (TBC)
+
+<hr>
+
+## v3.5.19 (2025-03-05)
 
 ### etcd server
 - Backport [add learner status check to readyz endpoint](https://github.com/etcd-io/etcd/pull/19280).
@@ -13,7 +17,9 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
 - Backport [add mixed read-write performance evaluation scripts](https://github.com/etcd-io/etcd/pull/19275).
 
 ### Dependencies
-- Compile binaries using [go 1.23.6](https://github.com/etcd-io/etcd/pull/19430).
+- Compile binaries using [go 1.23.7](https://github.com/etcd-io/etcd/pull/19528).
+- Bump [golang.org/x/crypto to v0.35.0 to address CVE-2025-22869](https://github.com/etcd-io/etcd/pull/19478).
+- Bump [golang.org/x/net to v0.36.0 to address CVE-2025-22870](https://github.com/etcd-io/etcd/pull/19530).
 
 <hr>
 
diff --git a/CHANGELOG/CHANGELOG-3.6.md b/CHANGELOG/CHANGELOG-3.6.md
index 2192e3076..73023a17b 100644
--- a/CHANGELOG/CHANGELOG-3.6.md
+++ b/CHANGELOG/CHANGELOG-3.6.md
@@ -8,6 +8,40 @@ Previous change logs can be found at [CHANGELOG-3.5](https://github.com/etcd-io/
 
 <hr>
 
+## v3.6.0-rc.3 (TBD)
+
+<hr>
+
+## v3.6.0-rc.2 (2025-03-05)
+
+### etcd server
+
+- Add [Prometheus metric to query server feature gates](https://github.com/etcd-io/etcd/pull/19495).
+
+### Dependencies
+
+- Compile binaries using [go 1.23.7](https://github.com/etcd-io/etcd/pull/19527).
+- Bump [golang.org/x/net to v0.36.0 to address CVE-2025-22870](https://github.com/etcd-io/etcd/pull/19531).
+- Bump [github.com/grpc-ecosystem/grpc-gateway/v2 to v2.26.3 to fix the issue of etcdserver crashing on receiving REST watch stream requests](https://github.com/etcd-io/etcd/pull/19522).
+
+<hr>
+
+## v3.6.0-rc.1 (2025-02-25)
+
+### etcdctl v3
+
+- Add [`DowngradeInfo` in result of endpoint status](https://github.com/etcd-io/etcd/pull/19471)
+
+### etcd server
+
+- Add [`DowngradeInfo` to endpoint status response](https://github.com/etcd-io/etcd/pull/19471)
+
+### Dependencies
+
+- Bump [golang.org/x/crypto to v0.35.0 to address CVE-2025-22869](https://github.com/etcd-io/etcd/pull/19480).
+
+<hr>
+
 ## v3.6.0-rc.0 (2025-02-13)
 
 See [code changes](https://github.com/etcd-io/etcd/compare/v3.5.0...v3.6.0).
diff --git a/CHANGELOG/CHANGELOG-3.7.md b/CHANGELOG/CHANGELOG-3.7.md
new file mode 100644
index 000000000..ceb11e53f
--- /dev/null
+++ b/CHANGELOG/CHANGELOG-3.7.md
@@ -0,0 +1,11 @@
+
+
+Previous change logs can be found at [CHANGELOG-3.6](https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.6.md).
+
+<hr>
+
+## v3.7.0 (TBD)
+
+### Deprecations
+
+- Deprecated [UsageFunc in pkg/cobrautl](https://github.com/etcd-io/etcd/pull/18356).
diff --git a/Documentation/contributor-guide/release.md b/Documentation/contributor-guide/release.md
index 671bbfead..54f7f7646 100644
--- a/Documentation/contributor-guide/release.md
+++ b/Documentation/contributor-guide/release.md
@@ -6,16 +6,18 @@ The procedure includes some manual steps for sanity checking, but it can probabl
 
 ## Release management
 
-The following pool of release candidates manages the release of each etcd major/minor version as well as manages patches
+Under the leadership of **James Blair** [@jmhbnz](https://github.com/jmhbnz) and **Ivan Valdes Castillo** [@ivanvc](https://github.com/ivanvc), the following pool of release candidates manages the release of each etcd major/minor version as well as manages patches
 to each stable release branch. They are responsible for communicating the timelines and status of each release and
 for ensuring the stability of the release branch.
 
 - Benjamin Wang [@ahrtr](https://github.com/ahrtr)
+- Fu Wei [@fuweid](https://github.com/fuweid)
 - James Blair [@jmhbnz](https://github.com/jmhbnz)
+- Ivan Valdes Castillo [@ivanvc](https://github.com/ivanvc)
 - Marek Siarkowicz [@serathius](https://github.com/serathius)
 - Sahdev Zala [@spzala](https://github.com/spzala)
+- Siyuan Zhang [@siyuanfoundation](https://github.com/siyuanfoundation)
 - Wenjia Zhang [@wenjiaswe](https://github.com/wenjiaswe)
-- Ivan Valdes Castillo [@ivanvc](https://github.com/ivanvc)
 
 All release version numbers follow the format of [semantic versioning 2.0.0](http://semver.org/).
 
diff --git a/Documentation/dev-guide/apispec/swagger/rpc.swagger.json b/Documentation/dev-guide/apispec/swagger/rpc.swagger.json
index b2e0a00b2..34fc55dff 100644
--- a/Documentation/dev-guide/apispec/swagger/rpc.swagger.json
+++ b/Documentation/dev-guide/apispec/swagger/rpc.swagger.json
@@ -2135,6 +2135,19 @@
         }
       }
     },
+    "etcdserverpbDowngradeInfo": {
+      "type": "object",
+      "properties": {
+        "enabled": {
+          "type": "boolean",
+          "description": "enabled indicates whether the cluster is enabled to downgrade."
+        },
+        "targetVersion": {
+          "type": "string",
+          "description": "targetVersion is the target downgrade version."
+        }
+      }
+    },
     "etcdserverpbDowngradeRequest": {
       "type": "object",
       "properties": {
@@ -2689,7 +2702,7 @@
         "count": {
           "type": "string",
           "format": "int64",
-          "description": "count is set to the number of keys within the range when requested."
+          "description": "count is set to the actual number of keys within the range when requested.\nUnlike Kvs, it is unaffected by limits and filters (e.g., Min/Max, Create/Modify, Revisions)\nand reflects the full count within the specified range."
         }
       }
     },
@@ -2834,12 +2847,16 @@
         },
         "storageVersion": {
           "type": "string",
-          "description": "storageVersion is the version of the db file. It might be get updated with delay in relationship to the target cluster version."
+          "description": "storageVersion is the version of the db file. It might be updated with delay in relationship to the target cluster version."
         },
         "dbSizeQuota": {
           "type": "string",
           "format": "int64",
           "title": "dbSizeQuota is the configured etcd storage quota in bytes (the value passed to etcd instance by flag --quota-backend-bytes)"
+        },
+        "downgradeInfo": {
+          "$ref": "#/definitions/etcdserverpbDowngradeInfo",
+          "description": "downgradeInfo indicates if there is downgrade process."
         }
       }
     },
diff --git a/Documentation/dev-guide/apispec/swagger/v3election.swagger.json b/Documentation/dev-guide/apispec/swagger/v3election.swagger.json
index 75194fe04..d118221be 100644
--- a/Documentation/dev-guide/apispec/swagger/v3election.swagger.json
+++ b/Documentation/dev-guide/apispec/swagger/v3election.swagger.json
@@ -318,7 +318,7 @@
         "name": {
           "type": "string",
           "format": "byte",
-          "description": "name is the election identifier that correponds to the leadership key."
+          "description": "name is the election identifier that corresponds to the leadership key."
         },
         "key": {
           "type": "string",
diff --git a/api/etcdserverpb/gw/rpc.pb.gw.go b/api/etcdserverpb/gw/rpc.pb.gw.go
index 5e8132a2f..6ad1e9d9c 100644
--- a/api/etcdserverpb/gw/rpc.pb.gw.go
+++ b/api/etcdserverpb/gw/rpc.pb.gw.go
@@ -158,14 +158,12 @@ func local_request_KV_Compact_0(ctx context.Context, marshaler runtime.Marshaler
 	return protov1.MessageV2(msg), metadata, err
 }
 
-func request_Watch_Watch_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.WatchClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Watch_WatchClient, runtime.ServerMetadata, chan error, error) {
+func request_Watch_Watch_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.WatchClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Watch_WatchClient, runtime.ServerMetadata, error) {
 	var metadata runtime.ServerMetadata
-	errChan := make(chan error, 1)
 	stream, err := client.Watch(ctx)
 	if err != nil {
 		grpclog.Errorf("Failed to start streaming: %v", err)
-		close(errChan)
-		return nil, metadata, errChan, err
+		return nil, metadata, err
 	}
 	dec := marshaler.NewDecoder(req.Body)
 	handleSend := func() error {
@@ -185,10 +183,8 @@ func request_Watch_Watch_0(ctx context.Context, marshaler runtime.Marshaler, cli
 		return nil
 	}
 	go func() {
-		defer close(errChan)
 		for {
 			if err := handleSend(); err != nil {
-				errChan <- err
 				break
 			}
 		}
@@ -199,10 +195,10 @@ func request_Watch_Watch_0(ctx context.Context, marshaler runtime.Marshaler, cli
 	header, err := stream.Header()
 	if err != nil {
 		grpclog.Errorf("Failed to get header from client: %v", err)
-		return nil, metadata, errChan, err
+		return nil, metadata, err
 	}
 	metadata.HeaderMD = header
-	return stream, metadata, errChan, nil
+	return stream, metadata, nil
 }
 
 func request_Lease_LeaseGrant_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
@@ -277,14 +273,12 @@ func local_request_Lease_LeaseRevoke_1(ctx context.Context, marshaler runtime.Ma
 	return protov1.MessageV2(msg), metadata, err
 }
 
-func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Lease_LeaseKeepAliveClient, runtime.ServerMetadata, chan error, error) {
+func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Lease_LeaseKeepAliveClient, runtime.ServerMetadata, error) {
 	var metadata runtime.ServerMetadata
-	errChan := make(chan error, 1)
 	stream, err := client.LeaseKeepAlive(ctx)
 	if err != nil {
 		grpclog.Errorf("Failed to start streaming: %v", err)
-		close(errChan)
-		return nil, metadata, errChan, err
+		return nil, metadata, err
 	}
 	dec := marshaler.NewDecoder(req.Body)
 	handleSend := func() error {
@@ -304,10 +298,8 @@ func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marsh
 		return nil
 	}
 	go func() {
-		defer close(errChan)
 		for {
 			if err := handleSend(); err != nil {
-				errChan <- err
 				break
 			}
 		}
@@ -318,10 +310,10 @@ func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marsh
 	header, err := stream.Header()
 	if err != nil {
 		grpclog.Errorf("Failed to get header from client: %v", err)
-		return nil, metadata, errChan, err
+		return nil, metadata, err
 	}
 	metadata.HeaderMD = header
-	return stream, metadata, errChan, nil
+	return stream, metadata, nil
 }
 
 func request_Lease_LeaseTimeToLive_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
@@ -2221,20 +2213,12 @@ func RegisterWatchHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-
-		resp, md, reqErrChan, err := request_Watch_Watch_0(annotatedContext, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Watch_Watch_0(annotatedContext, inboundMarshaler, client, req, pathParams)
 		annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
 		if err != nil {
 			runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		go func() {
-			for err := range reqErrChan {
-				if err != nil && !errors.Is(err, io.EOF) {
-					runtime.HTTPStreamError(annotatedContext, mux, outboundMarshaler, w, req, err)
-				}
-			}
-		}()
 		forward_Watch_Watch_0(annotatedContext, mux, outboundMarshaler, w, req, func() (proto.Message, error) {
 			m1, err := resp.Recv()
 			return protov1.MessageV2(m1), err
@@ -2347,20 +2331,12 @@ func RegisterLeaseHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-
-		resp, md, reqErrChan, err := request_Lease_LeaseKeepAlive_0(annotatedContext, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Lease_LeaseKeepAlive_0(annotatedContext, inboundMarshaler, client, req, pathParams)
 		annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
 		if err != nil {
 			runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		go func() {
-			for err := range reqErrChan {
-				if err != nil && !errors.Is(err, io.EOF) {
-					runtime.HTTPStreamError(annotatedContext, mux, outboundMarshaler, w, req, err)
-				}
-			}
-		}()
 		forward_Lease_LeaseKeepAlive_0(annotatedContext, mux, outboundMarshaler, w, req, func() (proto.Message, error) {
 			m1, err := resp.Recv()
 			return protov1.MessageV2(m1), err
diff --git a/api/etcdserverpb/rpc.pb.go b/api/etcdserverpb/rpc.pb.go
index b313cc59a..42bf641db 100644
--- a/api/etcdserverpb/rpc.pb.go
+++ b/api/etcdserverpb/rpc.pb.go
@@ -529,7 +529,9 @@ type RangeResponse struct {
 	Kvs []*mvccpb.KeyValue `protobuf:"bytes,2,rep,name=kvs,proto3" json:"kvs,omitempty"`
 	// more indicates if there are more keys to return in the requested range.
 	More bool `protobuf:"varint,3,opt,name=more,proto3" json:"more,omitempty"`
-	// count is set to the number of keys within the range when requested.
+	// count is set to the actual number of keys within the range when requested.
+	// Unlike Kvs, it is unaffected by limits and filters (e.g., Min/Max, Create/Modify, Revisions)
+	// and reflects the full count within the specified range.
 	Count                int64    `protobuf:"varint,4,opt,name=count,proto3" json:"count,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
@@ -4299,13 +4301,15 @@ type StatusResponse struct {
 	DbSizeInUse int64 `protobuf:"varint,9,opt,name=dbSizeInUse,proto3" json:"dbSizeInUse,omitempty"`
 	// isLearner indicates if the member is raft learner.
 	IsLearner bool `protobuf:"varint,10,opt,name=isLearner,proto3" json:"isLearner,omitempty"`
-	// storageVersion is the version of the db file. It might be get updated with delay in relationship to the target cluster version.
+	// storageVersion is the version of the db file. It might be updated with delay in relationship to the target cluster version.
 	StorageVersion string `protobuf:"bytes,11,opt,name=storageVersion,proto3" json:"storageVersion,omitempty"`
 	// dbSizeQuota is the configured etcd storage quota in bytes (the value passed to etcd instance by flag --quota-backend-bytes)
-	DbSizeQuota          int64    `protobuf:"varint,12,opt,name=dbSizeQuota,proto3" json:"dbSizeQuota,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
+	DbSizeQuota int64 `protobuf:"varint,12,opt,name=dbSizeQuota,proto3" json:"dbSizeQuota,omitempty"`
+	// downgradeInfo indicates if there is downgrade process.
+	DowngradeInfo        *DowngradeInfo `protobuf:"bytes,13,opt,name=downgradeInfo,proto3" json:"downgradeInfo,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
+	XXX_unrecognized     []byte         `json:"-"`
+	XXX_sizecache        int32          `json:"-"`
 }
 
 func (m *StatusResponse) Reset()         { *m = StatusResponse{} }
@@ -4425,6 +4429,70 @@ func (m *StatusResponse) GetDbSizeQuota() int64 {
 	return 0
 }
 
+func (m *StatusResponse) GetDowngradeInfo() *DowngradeInfo {
+	if m != nil {
+		return m.DowngradeInfo
+	}
+	return nil
+}
+
+type DowngradeInfo struct {
+	// enabled indicates whether the cluster is enabled to downgrade.
+	Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
+	// targetVersion is the target downgrade version.
+	TargetVersion        string   `protobuf:"bytes,2,opt,name=targetVersion,proto3" json:"targetVersion,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *DowngradeInfo) Reset()         { *m = DowngradeInfo{} }
+func (m *DowngradeInfo) String() string { return proto.CompactTextString(m) }
+func (*DowngradeInfo) ProtoMessage()    {}
+func (*DowngradeInfo) Descriptor() ([]byte, []int) {
+	return fileDescriptor_77a6da22d6a3feb1, []int{62}
+}
+func (m *DowngradeInfo) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *DowngradeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_DowngradeInfo.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *DowngradeInfo) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DowngradeInfo.Merge(m, src)
+}
+func (m *DowngradeInfo) XXX_Size() int {
+	return m.Size()
+}
+func (m *DowngradeInfo) XXX_DiscardUnknown() {
+	xxx_messageInfo_DowngradeInfo.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DowngradeInfo proto.InternalMessageInfo
+
+func (m *DowngradeInfo) GetEnabled() bool {
+	if m != nil {
+		return m.Enabled
+	}
+	return false
+}
+
+func (m *DowngradeInfo) GetTargetVersion() string {
+	if m != nil {
+		return m.TargetVersion
+	}
+	return ""
+}
+
 type AuthEnableRequest struct {
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
@@ -4435,7 +4503,7 @@ func (m *AuthEnableRequest) Reset()         { *m = AuthEnableRequest{} }
 func (m *AuthEnableRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthEnableRequest) ProtoMessage()    {}
 func (*AuthEnableRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{62}
+	return fileDescriptor_77a6da22d6a3feb1, []int{63}
 }
 func (m *AuthEnableRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -4474,7 +4542,7 @@ func (m *AuthDisableRequest) Reset()         { *m = AuthDisableRequest{} }
 func (m *AuthDisableRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthDisableRequest) ProtoMessage()    {}
 func (*AuthDisableRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{63}
+	return fileDescriptor_77a6da22d6a3feb1, []int{64}
 }
 func (m *AuthDisableRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -4513,7 +4581,7 @@ func (m *AuthStatusRequest) Reset()         { *m = AuthStatusRequest{} }
 func (m *AuthStatusRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthStatusRequest) ProtoMessage()    {}
 func (*AuthStatusRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{64}
+	return fileDescriptor_77a6da22d6a3feb1, []int{65}
 }
 func (m *AuthStatusRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -4554,7 +4622,7 @@ func (m *AuthenticateRequest) Reset()         { *m = AuthenticateRequest{} }
 func (m *AuthenticateRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthenticateRequest) ProtoMessage()    {}
 func (*AuthenticateRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{65}
+	return fileDescriptor_77a6da22d6a3feb1, []int{66}
 }
 func (m *AuthenticateRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -4611,7 +4679,7 @@ func (m *AuthUserAddRequest) Reset()         { *m = AuthUserAddRequest{} }
 func (m *AuthUserAddRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthUserAddRequest) ProtoMessage()    {}
 func (*AuthUserAddRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{66}
+	return fileDescriptor_77a6da22d6a3feb1, []int{67}
 }
 func (m *AuthUserAddRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -4679,7 +4747,7 @@ func (m *AuthUserGetRequest) Reset()         { *m = AuthUserGetRequest{} }
 func (m *AuthUserGetRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthUserGetRequest) ProtoMessage()    {}
 func (*AuthUserGetRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{67}
+	return fileDescriptor_77a6da22d6a3feb1, []int{68}
 }
 func (m *AuthUserGetRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -4727,7 +4795,7 @@ func (m *AuthUserDeleteRequest) Reset()         { *m = AuthUserDeleteRequest{} }
 func (m *AuthUserDeleteRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthUserDeleteRequest) ProtoMessage()    {}
 func (*AuthUserDeleteRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{68}
+	return fileDescriptor_77a6da22d6a3feb1, []int{69}
 }
 func (m *AuthUserDeleteRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -4779,7 +4847,7 @@ func (m *AuthUserChangePasswordRequest) Reset()         { *m = AuthUserChangePas
 func (m *AuthUserChangePasswordRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthUserChangePasswordRequest) ProtoMessage()    {}
 func (*AuthUserChangePasswordRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{69}
+	return fileDescriptor_77a6da22d6a3feb1, []int{70}
 }
 func (m *AuthUserChangePasswordRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -4843,7 +4911,7 @@ func (m *AuthUserGrantRoleRequest) Reset()         { *m = AuthUserGrantRoleReque
 func (m *AuthUserGrantRoleRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthUserGrantRoleRequest) ProtoMessage()    {}
 func (*AuthUserGrantRoleRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{70}
+	return fileDescriptor_77a6da22d6a3feb1, []int{71}
 }
 func (m *AuthUserGrantRoleRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -4898,7 +4966,7 @@ func (m *AuthUserRevokeRoleRequest) Reset()         { *m = AuthUserRevokeRoleReq
 func (m *AuthUserRevokeRoleRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthUserRevokeRoleRequest) ProtoMessage()    {}
 func (*AuthUserRevokeRoleRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{71}
+	return fileDescriptor_77a6da22d6a3feb1, []int{72}
 }
 func (m *AuthUserRevokeRoleRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -4953,7 +5021,7 @@ func (m *AuthRoleAddRequest) Reset()         { *m = AuthRoleAddRequest{} }
 func (m *AuthRoleAddRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleAddRequest) ProtoMessage()    {}
 func (*AuthRoleAddRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{72}
+	return fileDescriptor_77a6da22d6a3feb1, []int{73}
 }
 func (m *AuthRoleAddRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5000,7 +5068,7 @@ func (m *AuthRoleGetRequest) Reset()         { *m = AuthRoleGetRequest{} }
 func (m *AuthRoleGetRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleGetRequest) ProtoMessage()    {}
 func (*AuthRoleGetRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{73}
+	return fileDescriptor_77a6da22d6a3feb1, []int{74}
 }
 func (m *AuthRoleGetRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5046,7 +5114,7 @@ func (m *AuthUserListRequest) Reset()         { *m = AuthUserListRequest{} }
 func (m *AuthUserListRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthUserListRequest) ProtoMessage()    {}
 func (*AuthUserListRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{74}
+	return fileDescriptor_77a6da22d6a3feb1, []int{75}
 }
 func (m *AuthUserListRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5085,7 +5153,7 @@ func (m *AuthRoleListRequest) Reset()         { *m = AuthRoleListRequest{} }
 func (m *AuthRoleListRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleListRequest) ProtoMessage()    {}
 func (*AuthRoleListRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{75}
+	return fileDescriptor_77a6da22d6a3feb1, []int{76}
 }
 func (m *AuthRoleListRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5125,7 +5193,7 @@ func (m *AuthRoleDeleteRequest) Reset()         { *m = AuthRoleDeleteRequest{} }
 func (m *AuthRoleDeleteRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleDeleteRequest) ProtoMessage()    {}
 func (*AuthRoleDeleteRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{76}
+	return fileDescriptor_77a6da22d6a3feb1, []int{77}
 }
 func (m *AuthRoleDeleteRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5175,7 +5243,7 @@ func (m *AuthRoleGrantPermissionRequest) Reset()         { *m = AuthRoleGrantPer
 func (m *AuthRoleGrantPermissionRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleGrantPermissionRequest) ProtoMessage()    {}
 func (*AuthRoleGrantPermissionRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{77}
+	return fileDescriptor_77a6da22d6a3feb1, []int{78}
 }
 func (m *AuthRoleGrantPermissionRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5231,7 +5299,7 @@ func (m *AuthRoleRevokePermissionRequest) Reset()         { *m = AuthRoleRevokeP
 func (m *AuthRoleRevokePermissionRequest) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleRevokePermissionRequest) ProtoMessage()    {}
 func (*AuthRoleRevokePermissionRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{78}
+	return fileDescriptor_77a6da22d6a3feb1, []int{79}
 }
 func (m *AuthRoleRevokePermissionRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5292,7 +5360,7 @@ func (m *AuthEnableResponse) Reset()         { *m = AuthEnableResponse{} }
 func (m *AuthEnableResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthEnableResponse) ProtoMessage()    {}
 func (*AuthEnableResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{79}
+	return fileDescriptor_77a6da22d6a3feb1, []int{80}
 }
 func (m *AuthEnableResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5339,7 +5407,7 @@ func (m *AuthDisableResponse) Reset()         { *m = AuthDisableResponse{} }
 func (m *AuthDisableResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthDisableResponse) ProtoMessage()    {}
 func (*AuthDisableResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{80}
+	return fileDescriptor_77a6da22d6a3feb1, []int{81}
 }
 func (m *AuthDisableResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5389,7 +5457,7 @@ func (m *AuthStatusResponse) Reset()         { *m = AuthStatusResponse{} }
 func (m *AuthStatusResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthStatusResponse) ProtoMessage()    {}
 func (*AuthStatusResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{81}
+	return fileDescriptor_77a6da22d6a3feb1, []int{82}
 }
 func (m *AuthStatusResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5452,7 +5520,7 @@ func (m *AuthenticateResponse) Reset()         { *m = AuthenticateResponse{} }
 func (m *AuthenticateResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthenticateResponse) ProtoMessage()    {}
 func (*AuthenticateResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{82}
+	return fileDescriptor_77a6da22d6a3feb1, []int{83}
 }
 func (m *AuthenticateResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5506,7 +5574,7 @@ func (m *AuthUserAddResponse) Reset()         { *m = AuthUserAddResponse{} }
 func (m *AuthUserAddResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthUserAddResponse) ProtoMessage()    {}
 func (*AuthUserAddResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{83}
+	return fileDescriptor_77a6da22d6a3feb1, []int{84}
 }
 func (m *AuthUserAddResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5554,7 +5622,7 @@ func (m *AuthUserGetResponse) Reset()         { *m = AuthUserGetResponse{} }
 func (m *AuthUserGetResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthUserGetResponse) ProtoMessage()    {}
 func (*AuthUserGetResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{84}
+	return fileDescriptor_77a6da22d6a3feb1, []int{85}
 }
 func (m *AuthUserGetResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5608,7 +5676,7 @@ func (m *AuthUserDeleteResponse) Reset()         { *m = AuthUserDeleteResponse{}
 func (m *AuthUserDeleteResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthUserDeleteResponse) ProtoMessage()    {}
 func (*AuthUserDeleteResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{85}
+	return fileDescriptor_77a6da22d6a3feb1, []int{86}
 }
 func (m *AuthUserDeleteResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5655,7 +5723,7 @@ func (m *AuthUserChangePasswordResponse) Reset()         { *m = AuthUserChangePa
 func (m *AuthUserChangePasswordResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthUserChangePasswordResponse) ProtoMessage()    {}
 func (*AuthUserChangePasswordResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{86}
+	return fileDescriptor_77a6da22d6a3feb1, []int{87}
 }
 func (m *AuthUserChangePasswordResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5702,7 +5770,7 @@ func (m *AuthUserGrantRoleResponse) Reset()         { *m = AuthUserGrantRoleResp
 func (m *AuthUserGrantRoleResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthUserGrantRoleResponse) ProtoMessage()    {}
 func (*AuthUserGrantRoleResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{87}
+	return fileDescriptor_77a6da22d6a3feb1, []int{88}
 }
 func (m *AuthUserGrantRoleResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5749,7 +5817,7 @@ func (m *AuthUserRevokeRoleResponse) Reset()         { *m = AuthUserRevokeRoleRe
 func (m *AuthUserRevokeRoleResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthUserRevokeRoleResponse) ProtoMessage()    {}
 func (*AuthUserRevokeRoleResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{88}
+	return fileDescriptor_77a6da22d6a3feb1, []int{89}
 }
 func (m *AuthUserRevokeRoleResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5796,7 +5864,7 @@ func (m *AuthRoleAddResponse) Reset()         { *m = AuthRoleAddResponse{} }
 func (m *AuthRoleAddResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleAddResponse) ProtoMessage()    {}
 func (*AuthRoleAddResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{89}
+	return fileDescriptor_77a6da22d6a3feb1, []int{90}
 }
 func (m *AuthRoleAddResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5844,7 +5912,7 @@ func (m *AuthRoleGetResponse) Reset()         { *m = AuthRoleGetResponse{} }
 func (m *AuthRoleGetResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleGetResponse) ProtoMessage()    {}
 func (*AuthRoleGetResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{90}
+	return fileDescriptor_77a6da22d6a3feb1, []int{91}
 }
 func (m *AuthRoleGetResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5899,7 +5967,7 @@ func (m *AuthRoleListResponse) Reset()         { *m = AuthRoleListResponse{} }
 func (m *AuthRoleListResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleListResponse) ProtoMessage()    {}
 func (*AuthRoleListResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{91}
+	return fileDescriptor_77a6da22d6a3feb1, []int{92}
 }
 func (m *AuthRoleListResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -5954,7 +6022,7 @@ func (m *AuthUserListResponse) Reset()         { *m = AuthUserListResponse{} }
 func (m *AuthUserListResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthUserListResponse) ProtoMessage()    {}
 func (*AuthUserListResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{92}
+	return fileDescriptor_77a6da22d6a3feb1, []int{93}
 }
 func (m *AuthUserListResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -6008,7 +6076,7 @@ func (m *AuthRoleDeleteResponse) Reset()         { *m = AuthRoleDeleteResponse{}
 func (m *AuthRoleDeleteResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleDeleteResponse) ProtoMessage()    {}
 func (*AuthRoleDeleteResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{93}
+	return fileDescriptor_77a6da22d6a3feb1, []int{94}
 }
 func (m *AuthRoleDeleteResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -6055,7 +6123,7 @@ func (m *AuthRoleGrantPermissionResponse) Reset()         { *m = AuthRoleGrantPe
 func (m *AuthRoleGrantPermissionResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleGrantPermissionResponse) ProtoMessage()    {}
 func (*AuthRoleGrantPermissionResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{94}
+	return fileDescriptor_77a6da22d6a3feb1, []int{95}
 }
 func (m *AuthRoleGrantPermissionResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -6102,7 +6170,7 @@ func (m *AuthRoleRevokePermissionResponse) Reset()         { *m = AuthRoleRevoke
 func (m *AuthRoleRevokePermissionResponse) String() string { return proto.CompactTextString(m) }
 func (*AuthRoleRevokePermissionResponse) ProtoMessage()    {}
 func (*AuthRoleRevokePermissionResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_77a6da22d6a3feb1, []int{95}
+	return fileDescriptor_77a6da22d6a3feb1, []int{96}
 }
 func (m *AuthRoleRevokePermissionResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -6209,6 +6277,7 @@ func init() {
 	proto.RegisterType((*DowngradeVersionTestRequest)(nil), "etcdserverpb.DowngradeVersionTestRequest")
 	proto.RegisterType((*StatusRequest)(nil), "etcdserverpb.StatusRequest")
 	proto.RegisterType((*StatusResponse)(nil), "etcdserverpb.StatusResponse")
+	proto.RegisterType((*DowngradeInfo)(nil), "etcdserverpb.DowngradeInfo")
 	proto.RegisterType((*AuthEnableRequest)(nil), "etcdserverpb.AuthEnableRequest")
 	proto.RegisterType((*AuthDisableRequest)(nil), "etcdserverpb.AuthDisableRequest")
 	proto.RegisterType((*AuthStatusRequest)(nil), "etcdserverpb.AuthStatusRequest")
@@ -6248,291 +6317,293 @@ func init() {
 func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) }
 
 var fileDescriptor_77a6da22d6a3feb1 = []byte{
-	// 4532 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x3c, 0x4d, 0x6f, 0x1b, 0x49,
-	0x76, 0x6a, 0x52, 0x12, 0xc5, 0x47, 0x8a, 0xa2, 0xca, 0xb2, 0x4d, 0xd3, 0xb6, 0xac, 0x69, 0x8f,
-	0x67, 0x3d, 0x9e, 0xb1, 0x68, 0x4b, 0xf6, 0xcc, 0xc6, 0xc1, 0x4c, 0x96, 0x96, 0x38, 0xb6, 0x62,
-	0x59, 0xd2, 0xb4, 0x68, 0xcf, 0x8e, 0x03, 0xac, 0xd2, 0x22, 0xcb, 0x54, 0xaf, 0xc8, 0x6e, 0x6e,
-	0x77, 0x8b, 0x96, 0x26, 0x87, 0x9d, 0x6c, 0xb2, 0x59, 0x6c, 0x02, 0x2c, 0x90, 0x09, 0x10, 0x2c,
-	0x82, 0xe4, 0x12, 0x04, 0x48, 0x0e, 0x49, 0x90, 0x1c, 0x72, 0x08, 0x12, 0x20, 0x87, 0xe4, 0x90,
-	0x1c, 0x02, 0x04, 0xc8, 0x21, 0xd7, 0x64, 0xb2, 0xa7, 0xfc, 0x8a, 0xa0, 0xbe, 0xba, 0xaa, 0xbb,
-	0xab, 0x25, 0xcf, 0x4a, 0x83, 0xbd, 0x58, 0x5d, 0xf5, 0x5e, 0xbd, 0xf7, 0xea, 0xbd, 0xaa, 0xf7,
-	0xaa, 0xde, 0x2b, 0x13, 0x8a, 0xfe, 0xb0, 0xb3, 0x38, 0xf4, 0xbd, 0xd0, 0x43, 0x65, 0x1c, 0x76,
-	0xba, 0x01, 0xf6, 0x47, 0xd8, 0x1f, 0xee, 0xd6, 0xe7, 0x7a, 0x5e, 0xcf, 0xa3, 0x80, 0x06, 0xf9,
-	0x62, 0x38, 0xf5, 0x1a, 0xc1, 0x69, 0xd8, 0x43, 0xa7, 0x31, 0x18, 0x75, 0x3a, 0xc3, 0xdd, 0xc6,
-	0xfe, 0x88, 0x43, 0xea, 0x11, 0xc4, 0x3e, 0x08, 0xf7, 0x86, 0xbb, 0xf4, 0x0f, 0x87, 0x2d, 0x44,
-	0xb0, 0x11, 0xf6, 0x03, 0xc7, 0x73, 0x87, 0xbb, 0xe2, 0x8b, 0x63, 0x5c, 0xe9, 0x79, 0x5e, 0xaf,
-	0x8f, 0xd9, 0x78, 0xd7, 0xf5, 0x42, 0x3b, 0x74, 0x3c, 0x37, 0xe0, 0x50, 0xf6, 0xa7, 0x73, 0xbb,
-	0x87, 0xdd, 0xdb, 0xde, 0x10, 0xbb, 0xf6, 0xd0, 0x19, 0x2d, 0x35, 0xbc, 0x21, 0xc5, 0x49, 0xe3,
-	0x9b, 0x3f, 0x31, 0xa0, 0x62, 0xe1, 0x60, 0xe8, 0xb9, 0x01, 0x7e, 0x8c, 0xed, 0x2e, 0xf6, 0xd1,
-	0x55, 0x80, 0x4e, 0xff, 0x20, 0x08, 0xb1, 0xbf, 0xe3, 0x74, 0x6b, 0xc6, 0x82, 0x71, 0x73, 0xdc,
-	0x2a, 0xf2, 0x9e, 0xb5, 0x2e, 0xba, 0x0c, 0xc5, 0x01, 0x1e, 0xec, 0x32, 0x68, 0x8e, 0x42, 0xa7,
-	0x58, 0xc7, 0x5a, 0x17, 0xd5, 0x61, 0xca, 0xc7, 0x23, 0x87, 0x88, 0x5b, 0xcb, 0x2f, 0x18, 0x37,
-	0xf3, 0x56, 0xd4, 0x26, 0x03, 0x7d, 0xfb, 0x65, 0xb8, 0x13, 0x62, 0x7f, 0x50, 0x1b, 0x67, 0x03,
-	0x49, 0x47, 0x1b, 0xfb, 0x83, 0x07, 0x85, 0x1f, 0xfc, 0x5d, 0x2d, 0xbf, 0xbc, 0x78, 0xc7, 0xfc,
-	0xe7, 0x09, 0x28, 0x5b, 0xb6, 0xdb, 0xc3, 0x16, 0xfe, 0xde, 0x01, 0x0e, 0x42, 0x54, 0x85, 0xfc,
-	0x3e, 0x3e, 0xa2, 0x72, 0x94, 0x2d, 0xf2, 0xc9, 0x08, 0xb9, 0x3d, 0xbc, 0x83, 0x5d, 0x26, 0x41,
-	0x99, 0x10, 0x72, 0x7b, 0xb8, 0xe5, 0x76, 0xd1, 0x1c, 0x4c, 0xf4, 0x9d, 0x81, 0x13, 0x72, 0xf6,
-	0xac, 0x11, 0x93, 0x6b, 0x3c, 0x21, 0xd7, 0x0a, 0x40, 0xe0, 0xf9, 0xe1, 0x8e, 0xe7, 0x77, 0xb1,
-	0x5f, 0x9b, 0x58, 0x30, 0x6e, 0x56, 0x96, 0xde, 0x5c, 0x54, 0x2d, 0xbc, 0xa8, 0x0a, 0xb4, 0xb8,
-	0xed, 0xf9, 0xe1, 0x26, 0xc1, 0xb5, 0x8a, 0x81, 0xf8, 0x44, 0x1f, 0x41, 0x89, 0x12, 0x09, 0x6d,
-	0xbf, 0x87, 0xc3, 0xda, 0x24, 0xa5, 0x72, 0xe3, 0x04, 0x2a, 0x6d, 0x8a, 0x6c, 0x51, 0xf6, 0xec,
-	0x1b, 0x99, 0x50, 0x0e, 0xb0, 0xef, 0xd8, 0x7d, 0xe7, 0x33, 0x7b, 0xb7, 0x8f, 0x6b, 0x85, 0x05,
-	0xe3, 0xe6, 0x94, 0x15, 0xeb, 0x23, 0xf3, 0xdf, 0xc7, 0x47, 0xc1, 0x8e, 0xe7, 0xf6, 0x8f, 0x6a,
-	0x53, 0x14, 0x61, 0x8a, 0x74, 0x6c, 0xba, 0xfd, 0x23, 0x6a, 0x3d, 0xef, 0xc0, 0x0d, 0x19, 0xb4,
-	0x48, 0xa1, 0x45, 0xda, 0x43, 0xc1, 0x77, 0xa1, 0x3a, 0x70, 0xdc, 0x9d, 0x81, 0xd7, 0xdd, 0x89,
-	0x14, 0x02, 0x44, 0x21, 0x0f, 0x0b, 0xbf, 0x4b, 0x2d, 0x70, 0xd7, 0xaa, 0x0c, 0x1c, 0xf7, 0xa9,
-	0xd7, 0xb5, 0x84, 0x7e, 0xc8, 0x10, 0xfb, 0x30, 0x3e, 0xa4, 0x94, 0x1c, 0x62, 0x1f, 0xaa, 0x43,
-	0xde, 0x87, 0x73, 0x84, 0x4b, 0xc7, 0xc7, 0x76, 0x88, 0xe5, 0xa8, 0x72, 0x7c, 0xd4, 0xec, 0xc0,
-	0x71, 0x57, 0x28, 0x4a, 0x6c, 0xa0, 0x7d, 0x98, 0x1a, 0x38, 0x9d, 0x1c, 0x68, 0x1f, 0xc6, 0x07,
-	0x9a, 0xef, 0x43, 0x31, 0xb2, 0x0b, 0x9a, 0x82, 0xf1, 0x8d, 0xcd, 0x8d, 0x56, 0x75, 0x0c, 0x01,
-	0x4c, 0x36, 0xb7, 0x57, 0x5a, 0x1b, 0xab, 0x55, 0x03, 0x95, 0xa0, 0xb0, 0xda, 0x62, 0x8d, 0x5c,
-	0xbd, 0xf0, 0x05, 0x5f, 0x6f, 0x4f, 0x00, 0xa4, 0x29, 0x50, 0x01, 0xf2, 0x4f, 0x5a, 0x9f, 0x56,
-	0xc7, 0x08, 0xf2, 0xf3, 0x96, 0xb5, 0xbd, 0xb6, 0xb9, 0x51, 0x35, 0x08, 0x95, 0x15, 0xab, 0xd5,
-	0x6c, 0xb7, 0xaa, 0x39, 0x82, 0xf1, 0x74, 0x73, 0xb5, 0x9a, 0x47, 0x45, 0x98, 0x78, 0xde, 0x5c,
-	0x7f, 0xd6, 0xaa, 0x8e, 0x47, 0xc4, 0xe4, 0x2a, 0xfe, 0x63, 0x03, 0xa6, 0xb9, 0xb9, 0xd9, 0xde,
-	0x42, 0xf7, 0x60, 0x72, 0x8f, 0xee, 0x2f, 0xba, 0x92, 0x4b, 0x4b, 0x57, 0x12, 0x6b, 0x23, 0xb6,
-	0x07, 0x2d, 0x8e, 0x8b, 0x4c, 0xc8, 0xef, 0x8f, 0x82, 0x5a, 0x6e, 0x21, 0x7f, 0xb3, 0xb4, 0x54,
-	0x5d, 0x64, 0x9e, 0x64, 0xf1, 0x09, 0x3e, 0x7a, 0x6e, 0xf7, 0x0f, 0xb0, 0x45, 0x80, 0x08, 0xc1,
-	0xf8, 0xc0, 0xf3, 0x31, 0x5d, 0xf0, 0x53, 0x16, 0xfd, 0x26, 0xbb, 0x80, 0xda, 0x9c, 0x2f, 0x76,
-	0xd6, 0x90, 0xe2, 0xfd, 0xbb, 0x01, 0xb0, 0x75, 0x10, 0x66, 0x6f, 0xb1, 0x39, 0x98, 0x18, 0x11,
-	0x0e, 0x7c, 0x7b, 0xb1, 0x06, 0xdd, 0x5b, 0xd8, 0x0e, 0x70, 0xb4, 0xb7, 0x48, 0x03, 0x2d, 0x40,
-	0x61, 0xe8, 0xe3, 0xd1, 0xce, 0xfe, 0x88, 0x72, 0x9b, 0x92, 0x76, 0x9a, 0x24, 0xfd, 0x4f, 0x46,
-	0xe8, 0x16, 0x94, 0x9d, 0x9e, 0xeb, 0xf9, 0x78, 0x87, 0x11, 0x9d, 0x50, 0xd1, 0x96, 0xac, 0x12,
-	0x03, 0xd2, 0x29, 0x29, 0xb8, 0x8c, 0xd5, 0xa4, 0x16, 0x77, 0x9d, 0xc0, 0xe4, 0x7c, 0x3e, 0x37,
-	0xa0, 0x44, 0xe7, 0x73, 0x2a, 0x65, 0x2f, 0xc9, 0x89, 0xe4, 0xe8, 0xb0, 0x94, 0xc2, 0x53, 0x53,
-	0x93, 0x22, 0xb8, 0x80, 0x56, 0x71, 0x1f, 0x87, 0xf8, 0x34, 0xce, 0x4b, 0x51, 0x65, 0x5e, 0xab,
-	0x4a, 0xc9, 0xef, 0xcf, 0x0c, 0x38, 0x17, 0x63, 0x78, 0xaa, 0xa9, 0xd7, 0xa0, 0xd0, 0xa5, 0xc4,
-	0x98, 0x4c, 0x79, 0x4b, 0x34, 0xd1, 0x3d, 0x98, 0xe2, 0x22, 0x05, 0xb5, 0xbc, 0x7e, 0x19, 0x4a,
-	0x29, 0x0b, 0x4c, 0xca, 0x40, 0x8a, 0xf9, 0x0f, 0x39, 0x28, 0x72, 0x65, 0x6c, 0x0e, 0x51, 0x13,
-	0xa6, 0x7d, 0xd6, 0xd8, 0xa1, 0x73, 0xe6, 0x32, 0xd6, 0xb3, 0xfd, 0xe4, 0xe3, 0x31, 0xab, 0xcc,
-	0x87, 0xd0, 0x6e, 0xf4, 0xcb, 0x50, 0x12, 0x24, 0x86, 0x07, 0x21, 0x37, 0x54, 0x2d, 0x4e, 0x40,
-	0x2e, 0xed, 0xc7, 0x63, 0x16, 0x70, 0xf4, 0xad, 0x83, 0x10, 0xb5, 0x61, 0x4e, 0x0c, 0x66, 0xf3,
-	0xe3, 0x62, 0xe4, 0x29, 0x95, 0x85, 0x38, 0x95, 0xb4, 0x39, 0x1f, 0x8f, 0x59, 0x88, 0x8f, 0x57,
-	0x80, 0x68, 0x55, 0x8a, 0x14, 0x1e, 0xb2, 0xf8, 0x92, 0x12, 0xa9, 0x7d, 0xe8, 0x72, 0x22, 0x42,
-	0x5b, 0xcb, 0x8a, 0x6c, 0xed, 0x43, 0x37, 0x52, 0xd9, 0xc3, 0x22, 0x14, 0x78, 0xb7, 0xf9, 0x6f,
-	0x39, 0x00, 0x61, 0xb1, 0xcd, 0x21, 0x5a, 0x85, 0x8a, 0xcf, 0x5b, 0x31, 0xfd, 0x5d, 0xd6, 0xea,
-	0x8f, 0x1b, 0x7a, 0xcc, 0x9a, 0x16, 0x83, 0x98, 0xb8, 0x1f, 0x42, 0x39, 0xa2, 0x22, 0x55, 0x78,
-	0x49, 0xa3, 0xc2, 0x88, 0x42, 0x49, 0x0c, 0x20, 0x4a, 0xfc, 0x04, 0xce, 0x47, 0xe3, 0x35, 0x5a,
-	0x7c, 0xe3, 0x18, 0x2d, 0x46, 0x04, 0xcf, 0x09, 0x0a, 0xaa, 0x1e, 0x1f, 0x29, 0x82, 0x49, 0x45,
-	0x5e, 0xd2, 0x28, 0x92, 0x21, 0xa9, 0x9a, 0x8c, 0x24, 0x8c, 0xa9, 0x12, 0x48, 0xd8, 0x67, 0xfd,
-	0xe6, 0x5f, 0x8c, 0x43, 0x61, 0xc5, 0x1b, 0x0c, 0x6d, 0x9f, 0x2c, 0xa2, 0x49, 0x1f, 0x07, 0x07,
-	0xfd, 0x90, 0x2a, 0xb0, 0xb2, 0x74, 0x3d, 0xce, 0x83, 0xa3, 0x89, 0xbf, 0x16, 0x45, 0xb5, 0xf8,
-	0x10, 0x32, 0x98, 0x47, 0xf9, 0xdc, 0x6b, 0x0c, 0xe6, 0x31, 0x9e, 0x0f, 0x11, 0x0e, 0x21, 0x2f,
-	0x1d, 0x42, 0x1d, 0x0a, 0xfc, 0x80, 0xc7, 0x9c, 0xf5, 0xe3, 0x31, 0x4b, 0x74, 0xa0, 0xb7, 0x61,
-	0x26, 0x19, 0x0a, 0x27, 0x38, 0x4e, 0xa5, 0x13, 0x8f, 0x9c, 0xd7, 0xa1, 0x1c, 0x8b, 0xd0, 0x93,
-	0x1c, 0xaf, 0x34, 0x50, 0xe2, 0xf2, 0x05, 0xe1, 0xd6, 0xc9, 0xb1, 0xa2, 0xfc, 0x78, 0x4c, 0x38,
-	0xf6, 0x6b, 0xc2, 0xb1, 0x4f, 0xa9, 0x81, 0x96, 0xe8, 0x95, 0xfb, 0xf8, 0x37, 0x55, 0xaf, 0xf5,
-	0x2d, 0x32, 0x38, 0x42, 0x92, 0xee, 0xcb, 0xb4, 0x60, 0x3a, 0xa6, 0x32, 0x12, 0x23, 0x5b, 0x1f,
-	0x3f, 0x6b, 0xae, 0xb3, 0x80, 0xfa, 0x88, 0xc6, 0x50, 0xab, 0x6a, 0x90, 0x00, 0xbd, 0xde, 0xda,
-	0xde, 0xae, 0xe6, 0xd0, 0x05, 0x28, 0x6e, 0x6c, 0xb6, 0x77, 0x18, 0x56, 0xbe, 0x5e, 0xf8, 0x23,
-	0xe6, 0x49, 0x64, 0x7c, 0xfe, 0x34, 0xa2, 0xc9, 0x43, 0xb4, 0x12, 0x99, 0xc7, 0x94, 0xc8, 0x6c,
-	0x88, 0xc8, 0x9c, 0x93, 0x91, 0x39, 0x8f, 0x10, 0x4c, 0xac, 0xb7, 0x9a, 0xdb, 0x34, 0x48, 0x33,
-	0xd2, 0xcb, 0xe9, 0x68, 0xfd, 0xb0, 0x02, 0x65, 0x66, 0x9e, 0x9d, 0x03, 0x97, 0x1c, 0x26, 0xfe,
-	0xd2, 0x00, 0x90, 0x1b, 0x16, 0x35, 0xa0, 0xd0, 0x61, 0x22, 0xd4, 0x0c, 0xea, 0x01, 0xcf, 0x6b,
-	0x2d, 0x6e, 0x09, 0x2c, 0x74, 0x17, 0x0a, 0xc1, 0x41, 0xa7, 0x83, 0x03, 0x11, 0xb9, 0x2f, 0x26,
-	0x9d, 0x30, 0x77, 0x88, 0x96, 0xc0, 0x23, 0x43, 0x5e, 0xda, 0x4e, 0xff, 0x80, 0xc6, 0xf1, 0xe3,
-	0x87, 0x70, 0x3c, 0xe9, 0x63, 0xff, 0xd4, 0x80, 0x92, 0xb2, 0x2d, 0x7e, 0xce, 0x10, 0x70, 0x05,
-	0x8a, 0x54, 0x18, 0xdc, 0xe5, 0x41, 0x60, 0xca, 0x92, 0x1d, 0xe8, 0x3d, 0x28, 0x8a, 0x9d, 0x24,
-	0xe2, 0x40, 0x4d, 0x4f, 0x76, 0x73, 0x68, 0x49, 0x54, 0x29, 0x64, 0x1b, 0x66, 0xa9, 0x9e, 0x3a,
-	0xe4, 0xf6, 0x21, 0x34, 0xab, 0x1e, 0xcb, 0x8d, 0xc4, 0xb1, 0xbc, 0x0e, 0x53, 0xc3, 0xbd, 0xa3,
-	0xc0, 0xe9, 0xd8, 0x7d, 0x2e, 0x4e, 0xd4, 0x96, 0x54, 0xb7, 0x01, 0xa9, 0x54, 0x4f, 0xa3, 0x00,
-	0x49, 0xf4, 0x02, 0x94, 0x1e, 0xdb, 0xc1, 0x1e, 0x17, 0x52, 0xf6, 0xdf, 0x83, 0x69, 0xd2, 0xff,
-	0xe4, 0xf9, 0x6b, 0x88, 0x2f, 0x46, 0x2d, 0x9b, 0xff, 0x68, 0x40, 0x45, 0x0c, 0x3b, 0x95, 0x81,
-	0x10, 0x8c, 0xef, 0xd9, 0xc1, 0x1e, 0x55, 0xc6, 0xb4, 0x45, 0xbf, 0xd1, 0xdb, 0x50, 0xed, 0xb0,
-	0xf9, 0xef, 0x24, 0xee, 0x5d, 0x33, 0xbc, 0x3f, 0xda, 0xfb, 0xef, 0xc2, 0x34, 0x19, 0xb2, 0x13,
-	0xbf, 0x07, 0x89, 0x6d, 0xfc, 0x9e, 0x55, 0xde, 0xa3, 0x73, 0x4e, 0x8a, 0x6f, 0x43, 0x99, 0x29,
-	0xe3, 0xac, 0x65, 0x97, 0x7a, 0xad, 0xc3, 0xcc, 0xb6, 0x6b, 0x0f, 0x83, 0x3d, 0x2f, 0x4c, 0xe8,
-	0x7c, 0xd9, 0xfc, 0x5b, 0x03, 0xaa, 0x12, 0x78, 0x2a, 0x19, 0xbe, 0x01, 0x33, 0x3e, 0x1e, 0xd8,
-	0x8e, 0xeb, 0xb8, 0xbd, 0x9d, 0xdd, 0xa3, 0x10, 0x07, 0xfc, 0xfa, 0x5a, 0x89, 0xba, 0x1f, 0x92,
-	0x5e, 0x22, 0xec, 0x6e, 0xdf, 0xdb, 0xe5, 0x4e, 0x9a, 0x7e, 0xa3, 0x37, 0xe2, 0x5e, 0xba, 0x28,
-	0xf5, 0x26, 0xfa, 0xa5, 0xcc, 0x3f, 0xcd, 0x41, 0xf9, 0x13, 0x3b, 0xec, 0x88, 0x15, 0x84, 0xd6,
-	0xa0, 0x12, 0xb9, 0x71, 0xda, 0xc3, 0xe5, 0x4e, 0x1c, 0x38, 0xe8, 0x18, 0x71, 0xaf, 0x11, 0x07,
-	0x8e, 0xe9, 0x8e, 0xda, 0x41, 0x49, 0xd9, 0x6e, 0x07, 0xf7, 0x23, 0x52, 0xb9, 0x6c, 0x52, 0x14,
-	0x51, 0x25, 0xa5, 0x76, 0xa0, 0x6f, 0x43, 0x75, 0xe8, 0x7b, 0x3d, 0x1f, 0x07, 0x41, 0x44, 0x8c,
-	0x85, 0x70, 0x53, 0x43, 0x6c, 0x8b, 0xa3, 0x26, 0x4e, 0x31, 0xf7, 0x1e, 0x8f, 0x59, 0x33, 0xc3,
-	0x38, 0x4c, 0x3a, 0xd6, 0x19, 0x79, 0xde, 0x63, 0x9e, 0xf5, 0x47, 0x79, 0x40, 0xe9, 0x69, 0x7e,
-	0xd5, 0x63, 0xf2, 0x0d, 0xa8, 0x04, 0xa1, 0xed, 0xa7, 0xd6, 0xfc, 0x34, 0xed, 0x8d, 0x56, 0xfc,
-	0x37, 0x20, 0x92, 0x6c, 0xc7, 0xf5, 0x42, 0xe7, 0xe5, 0x11, 0xbb, 0xa0, 0x58, 0x15, 0xd1, 0xbd,
-	0x41, 0x7b, 0xd1, 0x06, 0x14, 0x5e, 0x3a, 0xfd, 0x10, 0xfb, 0x41, 0x6d, 0x62, 0x21, 0x7f, 0xb3,
-	0xb2, 0xf4, 0xce, 0x49, 0x86, 0x59, 0xfc, 0x88, 0xe2, 0xb7, 0x8f, 0x86, 0xea, 0xe9, 0x97, 0x13,
-	0x51, 0x8f, 0xf1, 0x93, 0xfa, 0x1b, 0x91, 0x09, 0x53, 0xaf, 0x08, 0xd1, 0x1d, 0xa7, 0x4b, 0x63,
-	0x71, 0xb4, 0x0f, 0xef, 0x59, 0x05, 0x0a, 0x58, 0xeb, 0xa2, 0xeb, 0x30, 0xf5, 0xd2, 0xb7, 0x7b,
-	0x03, 0xec, 0x86, 0xec, 0x96, 0x2f, 0x71, 0x22, 0x80, 0xb9, 0x08, 0x20, 0x45, 0x21, 0x91, 0x6f,
-	0x63, 0x73, 0xeb, 0x59, 0xbb, 0x3a, 0x86, 0xca, 0x30, 0xb5, 0xb1, 0xb9, 0xda, 0x5a, 0x6f, 0x91,
-	0xd8, 0x28, 0x62, 0xde, 0x5d, 0xb9, 0xe9, 0x9a, 0xc2, 0x10, 0xb1, 0x35, 0xa1, 0xca, 0x65, 0xc4,
-	0x2f, 0xdd, 0x42, 0x2e, 0x41, 0xe2, 0xae, 0x79, 0x0d, 0xe6, 0x74, 0x4b, 0x43, 0x20, 0xdc, 0x33,
-	0xff, 0x25, 0x07, 0xd3, 0x7c, 0x23, 0x9c, 0x6a, 0xe7, 0x5e, 0x52, 0xa4, 0xe2, 0xd7, 0x13, 0xa1,
-	0xa4, 0x1a, 0x14, 0xd8, 0x06, 0xe9, 0xf2, 0xfb, 0xaf, 0x68, 0x12, 0xe7, 0xcc, 0xd6, 0x3b, 0xee,
-	0x72, 0xb3, 0x47, 0x6d, 0xad, 0xdb, 0x9c, 0xc8, 0x74, 0x9b, 0xd1, 0x86, 0xb3, 0x03, 0x7e, 0xb0,
-	0x2a, 0x4a, 0x53, 0x94, 0xc5, 0xa6, 0x22, 0xc0, 0x98, 0xcd, 0x0a, 0x19, 0x36, 0x43, 0x37, 0x60,
-	0x12, 0x8f, 0xb0, 0x1b, 0x06, 0xb5, 0x12, 0x0d, 0xa4, 0xd3, 0xe2, 0x42, 0xd5, 0x22, 0xbd, 0x16,
-	0x07, 0x4a, 0x53, 0x7d, 0x08, 0xb3, 0xf4, 0xbe, 0xfb, 0xc8, 0xb7, 0x5d, 0xf5, 0xce, 0xde, 0x6e,
-	0xaf, 0xf3, 0xb0, 0x43, 0x3e, 0x51, 0x05, 0x72, 0x6b, 0xab, 0x5c, 0x3f, 0xb9, 0xb5, 0x55, 0x39,
-	0xfe, 0xf7, 0x0c, 0x40, 0x2a, 0x81, 0x53, 0xd9, 0x22, 0xc1, 0x45, 0xc8, 0x91, 0x97, 0x72, 0xcc,
-	0xc1, 0x04, 0xf6, 0x7d, 0xcf, 0x67, 0x8e, 0xd2, 0x62, 0x0d, 0x29, 0xcd, 0x6d, 0x2e, 0x8c, 0x85,
-	0x47, 0xde, 0x7e, 0xe4, 0x01, 0x18, 0x59, 0x23, 0x2d, 0x7c, 0x1b, 0xce, 0xc5, 0xd0, 0xcf, 0x26,
-	0xc4, 0x6f, 0xc2, 0x0c, 0xa5, 0xba, 0xb2, 0x87, 0x3b, 0xfb, 0x43, 0xcf, 0x71, 0x53, 0x12, 0xa0,
-	0xeb, 0xc4, 0x77, 0x89, 0x70, 0x41, 0xa6, 0xc8, 0xe6, 0x5c, 0x8e, 0x3a, 0xdb, 0xed, 0x75, 0xb9,
-	0xd4, 0x77, 0xe1, 0x42, 0x82, 0xa0, 0x98, 0xd9, 0xaf, 0x40, 0xa9, 0x13, 0x75, 0x06, 0xfc, 0x04,
-	0x79, 0x35, 0x2e, 0x6e, 0x72, 0xa8, 0x3a, 0x42, 0xf2, 0xf8, 0x36, 0x5c, 0x4c, 0xf1, 0x38, 0x0b,
-	0x75, 0xdc, 0x33, 0xef, 0xc0, 0x79, 0x4a, 0xf9, 0x09, 0xc6, 0xc3, 0x66, 0xdf, 0x19, 0x9d, 0x6c,
-	0x96, 0x23, 0x3e, 0x5f, 0x65, 0xc4, 0xd7, 0xbb, 0xac, 0x24, 0xeb, 0x16, 0x67, 0xdd, 0x76, 0x06,
-	0xb8, 0xed, 0xad, 0x67, 0x4b, 0x4b, 0x02, 0xf9, 0x3e, 0x3e, 0x0a, 0xf8, 0xf1, 0x91, 0x7e, 0x4b,
-	0xef, 0xf5, 0xd7, 0x06, 0x57, 0xa7, 0x4a, 0xe7, 0x6b, 0xde, 0x1a, 0xf3, 0x00, 0x3d, 0xb2, 0x07,
-	0x71, 0x97, 0x00, 0x58, 0x6e, 0x4e, 0xe9, 0x89, 0x04, 0x26, 0x51, 0xa8, 0x9c, 0x14, 0xf8, 0x2a,
-	0xdf, 0x38, 0xf4, 0x9f, 0x20, 0x75, 0x52, 0x7a, 0x0b, 0x4a, 0x14, 0xb2, 0x1d, 0xda, 0xe1, 0x41,
-	0x90, 0x65, 0xb9, 0x65, 0xf3, 0x47, 0x06, 0xdf, 0x51, 0x82, 0xce, 0xa9, 0xe6, 0x7c, 0x17, 0x26,
-	0xe9, 0x0d, 0x51, 0xdc, 0x74, 0x2e, 0x69, 0x16, 0x36, 0x93, 0xc8, 0xe2, 0x88, 0xca, 0x39, 0xc9,
-	0x80, 0xc9, 0xa7, 0xb4, 0x72, 0xa0, 0x48, 0x3b, 0x2e, 0x2c, 0xe7, 0xda, 0x03, 0x96, 0x7e, 0x2c,
-	0x5a, 0xf4, 0x9b, 0x5e, 0x08, 0x30, 0xf6, 0x9f, 0x59, 0xeb, 0xec, 0x06, 0x52, 0xb4, 0xa2, 0x36,
-	0x51, 0x6c, 0xa7, 0xef, 0x60, 0x37, 0xa4, 0xd0, 0x71, 0x0a, 0x55, 0x7a, 0xd0, 0x0d, 0x28, 0x3a,
-	0xc1, 0x3a, 0xb6, 0x7d, 0x97, 0xa7, 0xf8, 0x15, 0xc7, 0x2c, 0x21, 0x72, 0x8d, 0x7d, 0x07, 0xaa,
-	0x4c, 0xb2, 0x66, 0xb7, 0xab, 0x9c, 0xf6, 0x23, 0xfe, 0x46, 0x82, 0x7f, 0x8c, 0x7e, 0xee, 0x64,
-	0xfa, 0x7f, 0x63, 0xc0, 0xac, 0xc2, 0xe0, 0x54, 0x26, 0x78, 0x17, 0x26, 0x59, 0xfd, 0x85, 0x1f,
-	0x05, 0xe7, 0xe2, 0xa3, 0x18, 0x1b, 0x8b, 0xe3, 0xa0, 0x45, 0x28, 0xb0, 0x2f, 0x71, 0x8d, 0xd3,
-	0xa3, 0x0b, 0x24, 0x29, 0xf2, 0x22, 0x9c, 0xe3, 0x30, 0x3c, 0xf0, 0x74, 0x7b, 0x6e, 0x3c, 0xee,
-	0x21, 0x7e, 0x68, 0xc0, 0x5c, 0x7c, 0xc0, 0xa9, 0x66, 0xa9, 0xc8, 0x9d, 0xfb, 0x4a, 0x72, 0xff,
-	0xaa, 0x90, 0xfb, 0xd9, 0xb0, 0xab, 0x1c, 0x39, 0x93, 0x2b, 0x4e, 0xb5, 0x6e, 0x2e, 0x6e, 0x5d,
-	0x49, 0xeb, 0x27, 0xd1, 0x9c, 0x04, 0xb1, 0x53, 0xcd, 0xe9, 0xfd, 0xd7, 0x9a, 0x93, 0x72, 0x04,
-	0x4b, 0x4d, 0x6e, 0x4d, 0x2c, 0xa3, 0x75, 0x27, 0x88, 0x22, 0xce, 0x3b, 0x50, 0xee, 0x3b, 0x2e,
-	0xb6, 0x7d, 0x5e, 0x43, 0x32, 0xd4, 0xf5, 0x78, 0xdf, 0x8a, 0x01, 0x25, 0xa9, 0xdf, 0x32, 0x00,
-	0xa9, 0xb4, 0x7e, 0x31, 0xd6, 0x6a, 0x08, 0x05, 0x6f, 0xf9, 0xde, 0xc0, 0x0b, 0x4f, 0x5a, 0x66,
-	0xf7, 0xcc, 0xdf, 0x31, 0xe0, 0x7c, 0x62, 0xc4, 0x2f, 0x42, 0xf2, 0x7b, 0xe6, 0x15, 0x98, 0x5d,
-	0xc5, 0xe2, 0x8c, 0x97, 0xca, 0x1d, 0x6c, 0x03, 0x52, 0xa1, 0x67, 0x73, 0x8a, 0xf9, 0x26, 0xcc,
-	0x3e, 0xf5, 0x46, 0xc4, 0x91, 0x13, 0xb0, 0x74, 0x53, 0x2c, 0x99, 0x15, 0xe9, 0x2b, 0x6a, 0x4b,
-	0xd7, 0xbb, 0x0d, 0x48, 0x1d, 0x79, 0x16, 0xe2, 0x2c, 0x9b, 0xff, 0x63, 0x40, 0xb9, 0xd9, 0xb7,
-	0xfd, 0x81, 0x10, 0xe5, 0x43, 0x98, 0x64, 0x99, 0x19, 0x9e, 0x66, 0x7d, 0x2b, 0x4e, 0x4f, 0xc5,
-	0x65, 0x8d, 0x26, 0xcb, 0xe3, 0xf0, 0x51, 0x64, 0x2a, 0xbc, 0xb2, 0xbc, 0x9a, 0xa8, 0x34, 0xaf,
-	0xa2, 0xdb, 0x30, 0x61, 0x93, 0x21, 0x34, 0xbc, 0x56, 0x92, 0xe9, 0x32, 0x4a, 0x8d, 0x5c, 0x89,
-	0x2c, 0x86, 0x65, 0x7e, 0x00, 0x25, 0x85, 0x03, 0x2a, 0x40, 0xfe, 0x51, 0x8b, 0x5f, 0x93, 0x9a,
-	0x2b, 0xed, 0xb5, 0xe7, 0x2c, 0x85, 0x58, 0x01, 0x58, 0x6d, 0x45, 0xed, 0x9c, 0xa6, 0xb0, 0x67,
-	0x73, 0x3a, 0x3c, 0x6e, 0xa9, 0x12, 0x1a, 0x59, 0x12, 0xe6, 0x5e, 0x47, 0x42, 0xc9, 0xe2, 0x37,
-	0x0d, 0x98, 0xe6, 0xaa, 0x39, 0x6d, 0x68, 0xa6, 0x94, 0x33, 0x42, 0xb3, 0x32, 0x0d, 0x8b, 0x23,
-	0x4a, 0x19, 0xfe, 0xc9, 0x80, 0xea, 0xaa, 0xf7, 0xca, 0xed, 0xf9, 0x76, 0x37, 0xda, 0x83, 0x1f,
-	0x25, 0xcc, 0xb9, 0x98, 0xc8, 0xf4, 0x27, 0xf0, 0x65, 0x47, 0xc2, 0xac, 0x35, 0x99, 0x4b, 0x61,
-	0xf1, 0x5d, 0x34, 0xcd, 0x6f, 0xc1, 0x4c, 0x62, 0x10, 0x31, 0xd0, 0xf3, 0xe6, 0xfa, 0xda, 0x2a,
-	0x31, 0x08, 0xcd, 0xf7, 0xb6, 0x36, 0x9a, 0x0f, 0xd7, 0x5b, 0xbc, 0x2a, 0xdb, 0xdc, 0x58, 0x69,
-	0xad, 0x4b, 0x43, 0xdd, 0x17, 0x33, 0xb8, 0x6f, 0xf6, 0x61, 0x56, 0x11, 0xe8, 0xb4, 0xc5, 0x31,
-	0xbd, 0xbc, 0x92, 0xdb, 0x37, 0xe1, 0x72, 0xc4, 0xed, 0x39, 0x03, 0xb6, 0x71, 0xa0, 0x5e, 0xd6,
-	0x46, 0x9c, 0x69, 0xd1, 0x22, 0x9f, 0x62, 0xe4, 0x7b, 0x66, 0x0d, 0xa6, 0xf9, 0xf9, 0x28, 0xe9,
-	0x32, 0xfe, 0x2b, 0x0f, 0x15, 0x01, 0xfa, 0x7a, 0xe4, 0x47, 0x17, 0x60, 0xb2, 0xbb, 0xbb, 0xed,
-	0x7c, 0x26, 0x2a, 0xba, 0xbc, 0x45, 0xfa, 0xfb, 0x8c, 0x0f, 0x7b, 0xa7, 0xc1, 0x5b, 0xe8, 0x0a,
-	0x7b, 0xc2, 0xb1, 0xe6, 0x76, 0xf1, 0x21, 0x3d, 0x46, 0x8d, 0x5b, 0xb2, 0x83, 0xa6, 0x43, 0xf9,
-	0x7b, 0x0e, 0x7a, 0x4b, 0x56, 0xde, 0x77, 0xa0, 0x65, 0xa8, 0x92, 0xef, 0xe6, 0x70, 0xd8, 0x77,
-	0x70, 0x97, 0x11, 0x20, 0x17, 0xe4, 0x71, 0x79, 0x4e, 0x4a, 0x21, 0xa0, 0x6b, 0x30, 0x49, 0x2f,
-	0x8f, 0x41, 0x6d, 0x8a, 0x44, 0x64, 0x89, 0xca, 0xbb, 0xd1, 0xdb, 0x50, 0x62, 0x12, 0xaf, 0xb9,
-	0xcf, 0x02, 0x4c, 0x5f, 0x3b, 0x28, 0x99, 0x14, 0x15, 0x16, 0x3f, 0xa1, 0x41, 0xd6, 0x09, 0x0d,
-	0x35, 0xa0, 0x12, 0x84, 0x9e, 0x6f, 0xf7, 0x84, 0x19, 0xe9, 0x53, 0x07, 0x25, 0xdd, 0x97, 0x00,
-	0x4b, 0x11, 0x3e, 0x3e, 0xf0, 0x42, 0x3b, 0xfe, 0xc4, 0xe1, 0x3d, 0x4b, 0x85, 0x49, 0xcb, 0x5e,
-	0x81, 0xd9, 0xe6, 0x41, 0xb8, 0xd7, 0x72, 0x49, 0x04, 0x4e, 0xd9, 0xfd, 0x2a, 0x20, 0x02, 0x5d,
-	0x75, 0x02, 0x2d, 0x98, 0x0f, 0xd6, 0x2e, 0x9a, 0xfb, 0xe6, 0x06, 0x9c, 0x23, 0x50, 0xec, 0x86,
-	0x4e, 0x47, 0x39, 0xed, 0x88, 0xf3, 0xb4, 0x91, 0x38, 0x4f, 0xdb, 0x41, 0xf0, 0xca, 0xf3, 0xbb,
-	0x7c, 0x5d, 0x44, 0x6d, 0xc9, 0xed, 0xef, 0x0d, 0x26, 0xcd, 0xb3, 0x20, 0x76, 0x16, 0xfe, 0x8a,
-	0xf4, 0xd0, 0x2f, 0x41, 0x81, 0xbf, 0x41, 0xe2, 0x29, 0xc6, 0x0b, 0x8b, 0xec, 0xed, 0xd3, 0x22,
-	0x27, 0xbc, 0xc9, 0xa0, 0x4a, 0x1a, 0x8c, 0xe3, 0x13, 0x8b, 0xec, 0xd9, 0xc1, 0x1e, 0xee, 0x6e,
-	0x09, 0xe2, 0xb1, 0x04, 0xec, 0x7d, 0x2b, 0x01, 0x96, 0xb2, 0xdf, 0x95, 0xa2, 0x3f, 0xc2, 0xe1,
-	0x31, 0xa2, 0xab, 0x29, 0xfe, 0xf3, 0x62, 0x08, 0xaf, 0x4c, 0xbe, 0xce, 0xa8, 0x1f, 0x1b, 0x70,
-	0x55, 0x0c, 0x5b, 0xd9, 0xb3, 0xdd, 0x1e, 0x16, 0xc2, 0xfc, 0xbc, 0xfa, 0x4a, 0x4f, 0x3a, 0xff,
-	0x9a, 0x93, 0x7e, 0x02, 0xb5, 0x68, 0xd2, 0x34, 0xdd, 0xe3, 0xf5, 0xd5, 0x49, 0x1c, 0x04, 0x91,
-	0x1f, 0xa2, 0xdf, 0xa4, 0xcf, 0xf7, 0xfa, 0xd1, 0x4d, 0x8b, 0x7c, 0x4b, 0x62, 0xeb, 0x70, 0x49,
-	0x10, 0xe3, 0xf9, 0x97, 0x38, 0xb5, 0xd4, 0x9c, 0x8e, 0xa5, 0xc6, 0xed, 0x41, 0x68, 0x1c, 0xbf,
-	0x94, 0xb4, 0x43, 0xe2, 0x26, 0xa4, 0x5c, 0x0c, 0x1d, 0x97, 0x79, 0xb6, 0x03, 0x88, 0xcc, 0xca,
-	0xa1, 0x38, 0x05, 0x27, 0x24, 0xb5, 0x70, 0xbe, 0x04, 0x08, 0x3c, 0xb5, 0x04, 0xb2, 0xb9, 0x62,
-	0x98, 0x8f, 0x04, 0x25, 0x6a, 0xdf, 0xc2, 0xfe, 0xc0, 0x09, 0x02, 0xa5, 0xd6, 0xa5, 0x53, 0xd7,
-	0x5b, 0x30, 0x3e, 0xc4, 0xfc, 0x84, 0x50, 0x5a, 0x42, 0x62, 0x4f, 0x28, 0x83, 0x29, 0x5c, 0xb2,
-	0x19, 0xc0, 0x35, 0xc1, 0x86, 0x19, 0x44, 0xcb, 0x27, 0x29, 0xa6, 0xc8, 0xaf, 0xe7, 0x32, 0xf2,
-	0xeb, 0xf9, 0x78, 0x7e, 0x3d, 0x76, 0x6a, 0x55, 0x1d, 0xd5, 0xd9, 0x9c, 0x5a, 0xdb, 0xcc, 0x00,
-	0x91, 0x7f, 0x3b, 0x1b, 0xaa, 0xbf, 0xcf, 0x1d, 0xd5, 0x59, 0x45, 0x4c, 0x4c, 0xe7, 0x2c, 0x2a,
-	0xa1, 0xa2, 0x89, 0x4c, 0x28, 0x13, 0x23, 0x59, 0x6a, 0xe1, 0x61, 0xdc, 0x8a, 0xf5, 0x49, 0x67,
-	0xbc, 0x0f, 0x73, 0x71, 0x67, 0x7c, 0x2a, 0xa1, 0xe6, 0x60, 0x22, 0xf4, 0xf6, 0xb1, 0x08, 0xe2,
-	0xac, 0x91, 0x52, 0x6b, 0xe4, 0xa8, 0xcf, 0x46, 0xad, 0xdf, 0x95, 0x54, 0xe9, 0x06, 0x3c, 0xed,
-	0x0c, 0xc8, 0x72, 0x14, 0x17, 0x6c, 0xd6, 0x90, 0xbc, 0x3e, 0x81, 0x0b, 0x49, 0xe7, 0x7b, 0x36,
-	0x93, 0xd8, 0x61, 0x9b, 0x53, 0xe7, 0x9e, 0xcf, 0x86, 0xc1, 0x0b, 0xe9, 0x27, 0x15, 0xa7, 0x7b,
-	0x36, 0xb4, 0x7f, 0x0d, 0xea, 0x3a, 0x1f, 0x7c, 0xa6, 0x7b, 0x31, 0x72, 0xc9, 0x67, 0x43, 0xf5,
-	0x87, 0x86, 0x24, 0xab, 0xae, 0x9a, 0x0f, 0xbe, 0x0a, 0x59, 0x11, 0xeb, 0xee, 0x44, 0xcb, 0xa7,
-	0x11, 0x79, 0xcb, 0xbc, 0xde, 0x5b, 0xca, 0x21, 0x14, 0x51, 0xec, 0x3f, 0xe9, 0xea, 0xbf, 0xce,
-	0xd5, 0xcb, 0x99, 0xc9, 0xb8, 0x73, 0x5a, 0x66, 0x24, 0x3c, 0x47, 0xcc, 0x68, 0x23, 0xb5, 0x55,
-	0xd4, 0x20, 0x75, 0x36, 0xa6, 0xfb, 0x75, 0x19, 0x60, 0x52, 0x71, 0xec, 0x6c, 0x38, 0xd8, 0xb0,
-	0x90, 0x1d, 0xc2, 0xce, 0x84, 0xc5, 0xad, 0x26, 0x14, 0xa3, 0xeb, 0xb5, 0xf2, 0x18, 0xb8, 0x04,
-	0x85, 0x8d, 0xcd, 0xed, 0xad, 0xe6, 0x0a, 0xb9, 0x3d, 0xce, 0x41, 0x61, 0x65, 0xd3, 0xb2, 0x9e,
-	0x6d, 0xb5, 0xc9, 0xf5, 0x31, 0xf9, 0x36, 0x68, 0xe9, 0x67, 0x79, 0xc8, 0x3d, 0x79, 0x8e, 0x3e,
-	0x85, 0x09, 0xf6, 0x36, 0xed, 0x98, 0x27, 0x8a, 0xf5, 0xe3, 0x9e, 0xdf, 0x99, 0x17, 0x7f, 0xf0,
-	0x9f, 0x3f, 0xfb, 0x83, 0xdc, 0xac, 0x59, 0x6e, 0x8c, 0x96, 0x1b, 0xfb, 0xa3, 0x06, 0x0d, 0xb2,
-	0x0f, 0x8c, 0x5b, 0xe8, 0x63, 0xc8, 0x6f, 0x1d, 0x84, 0x28, 0xf3, 0xe9, 0x62, 0x3d, 0xfb, 0x45,
-	0x9e, 0x79, 0x9e, 0x12, 0x9d, 0x31, 0x81, 0x13, 0x1d, 0x1e, 0x84, 0x84, 0xe4, 0xf7, 0xa0, 0xa4,
-	0xbe, 0xa7, 0x3b, 0xf1, 0x3d, 0x63, 0xfd, 0xe4, 0xb7, 0x7a, 0xe6, 0x55, 0xca, 0xea, 0xa2, 0x89,
-	0x38, 0x2b, 0xf6, 0xe2, 0x4f, 0x9d, 0x45, 0xfb, 0xd0, 0x45, 0x99, 0xaf, 0x1d, 0xeb, 0xd9, 0xcf,
-	0xf7, 0x52, 0xb3, 0x08, 0x0f, 0x5d, 0x42, 0xf2, 0xbb, 0xfc, 0x9d, 0x5e, 0x27, 0x44, 0xd7, 0x34,
-	0x0f, 0xad, 0xd4, 0x07, 0x44, 0xf5, 0x85, 0x6c, 0x04, 0xce, 0xe4, 0x0a, 0x65, 0x72, 0xc1, 0x9c,
-	0xe5, 0x4c, 0x3a, 0x11, 0xca, 0x03, 0xe3, 0xd6, 0x52, 0x07, 0x26, 0x68, 0x81, 0x1a, 0xbd, 0x10,
-	0x1f, 0x75, 0x4d, 0xe9, 0x3f, 0xc3, 0xd0, 0xb1, 0xd2, 0xb6, 0x39, 0x47, 0x19, 0x55, 0xcc, 0x22,
-	0x61, 0x44, 0xcb, 0xd3, 0x0f, 0x8c, 0x5b, 0x37, 0x8d, 0x3b, 0xc6, 0xd2, 0x5f, 0x4d, 0xc0, 0x04,
-	0x2d, 0x84, 0xa0, 0x7d, 0x00, 0x59, 0x88, 0x4d, 0xce, 0x2e, 0x55, 0xe3, 0x4d, 0xce, 0x2e, 0x5d,
-	0xc3, 0x35, 0xeb, 0x94, 0xe9, 0x9c, 0x39, 0x43, 0x98, 0xd2, 0xfa, 0x4a, 0x83, 0x96, 0x93, 0x88,
-	0x1e, 0x7f, 0x6c, 0xf0, 0x8a, 0x10, 0xdb, 0x66, 0x48, 0x47, 0x2d, 0x56, 0x84, 0x4d, 0x2e, 0x07,
-	0x4d, 0xdd, 0xd5, 0xbc, 0x4f, 0x19, 0x36, 0xcc, 0xaa, 0x64, 0xe8, 0x53, 0x8c, 0x07, 0xc6, 0xad,
-	0x17, 0x35, 0xf3, 0x1c, 0xd7, 0x72, 0x02, 0x82, 0xbe, 0x0f, 0x95, 0x78, 0xb9, 0x10, 0x5d, 0xd7,
-	0xf0, 0x4a, 0x96, 0x1f, 0xeb, 0x6f, 0x1e, 0x8f, 0xc4, 0x65, 0x9a, 0xa7, 0x32, 0x71, 0xe6, 0x8c,
-	0xf3, 0x3e, 0xc6, 0x43, 0x9b, 0x20, 0x71, 0x1b, 0xa0, 0x3f, 0x31, 0x78, 0xc5, 0x57, 0x56, 0xfb,
-	0x90, 0x8e, 0x7a, 0xaa, 0xa8, 0x58, 0xbf, 0x71, 0x02, 0x16, 0x17, 0xe2, 0x03, 0x2a, 0xc4, 0xfb,
-	0xe6, 0x9c, 0x14, 0x22, 0x74, 0x06, 0x38, 0xf4, 0xb8, 0x14, 0x2f, 0xae, 0x98, 0x17, 0x63, 0xca,
-	0x89, 0x41, 0xa5, 0xb1, 0x58, 0x55, 0x4e, 0x6b, 0xac, 0x58, 0xe1, 0x4f, 0x6b, 0xac, 0x78, 0x49,
-	0x4f, 0x67, 0x2c, 0x5e, 0x83, 0xd3, 0x18, 0x2b, 0x82, 0x2c, 0xfd, 0xdf, 0x38, 0x14, 0x56, 0xd8,
-	0xff, 0xf7, 0x41, 0x1e, 0x14, 0xa3, 0x3a, 0x15, 0x9a, 0xd7, 0xa5, 0xc2, 0xe5, 0x55, 0xae, 0x7e,
-	0x2d, 0x13, 0xce, 0x05, 0x7a, 0x83, 0x0a, 0x74, 0xd9, 0xbc, 0x40, 0x38, 0xf3, 0xff, 0x52, 0xd4,
-	0x60, 0x09, 0xd3, 0x86, 0xdd, 0xed, 0x12, 0x45, 0xfc, 0x06, 0x94, 0xd5, 0xaa, 0x11, 0x7a, 0x43,
-	0x9b, 0x7e, 0x57, 0x4b, 0x50, 0x75, 0xf3, 0x38, 0x14, 0xce, 0xf9, 0x4d, 0xca, 0x79, 0xde, 0xbc,
-	0xa4, 0xe1, 0xec, 0x53, 0xd4, 0x18, 0x73, 0x56, 0xde, 0xd1, 0x33, 0x8f, 0xd5, 0x91, 0xf4, 0xcc,
-	0xe3, 0xd5, 0xa1, 0x63, 0x99, 0x1f, 0x50, 0x54, 0xc2, 0x3c, 0x00, 0x90, 0xf5, 0x17, 0xa4, 0xd5,
-	0xa5, 0x72, 0x61, 0x4d, 0x3a, 0x87, 0x74, 0xe9, 0xc6, 0x34, 0x29, 0x5b, 0xbe, 0xee, 0x12, 0x6c,
-	0xfb, 0x4e, 0x10, 0xb2, 0x8d, 0x39, 0x1d, 0xab, 0x9e, 0x20, 0xed, 0x7c, 0xe2, 0xc5, 0x98, 0xfa,
-	0xf5, 0x63, 0x71, 0x38, 0xf7, 0x1b, 0x94, 0xfb, 0x35, 0xb3, 0xae, 0xe1, 0x3e, 0x64, 0xb8, 0x64,
-	0xb1, 0x7d, 0x5e, 0x80, 0xd2, 0x53, 0xdb, 0x71, 0x43, 0xec, 0xda, 0x6e, 0x07, 0xa3, 0x5d, 0x98,
-	0xa0, 0xb1, 0x3b, 0xe9, 0x88, 0xd5, 0x62, 0x41, 0xd2, 0x11, 0xc7, 0xb2, 0xe5, 0xe6, 0x02, 0x65,
-	0x5c, 0x37, 0xcf, 0x13, 0xc6, 0x03, 0x49, 0xba, 0xc1, 0xf2, 0xec, 0xc6, 0x2d, 0xf4, 0x12, 0x26,
-	0x79, 0x95, 0x3c, 0x41, 0x28, 0x96, 0x54, 0xab, 0x5f, 0xd1, 0x03, 0x75, 0x6b, 0x59, 0x65, 0x13,
-	0x50, 0x3c, 0xc2, 0x67, 0x04, 0x20, 0x8b, 0x3e, 0x49, 0x8b, 0xa6, 0x8a, 0x45, 0xf5, 0x85, 0x6c,
-	0x04, 0x9d, 0x4e, 0x55, 0x9e, 0xdd, 0x08, 0x97, 0xf0, 0xfd, 0x0e, 0x8c, 0x3f, 0xb6, 0x83, 0x3d,
-	0x94, 0x88, 0xbd, 0xca, 0xa3, 0xd6, 0x7a, 0x5d, 0x07, 0xe2, 0x5c, 0xae, 0x51, 0x2e, 0x97, 0x98,
-	0x2b, 0x53, 0xb9, 0xd0, 0x67, 0x9b, 0x4c, 0x7f, 0xec, 0x45, 0x6b, 0x52, 0x7f, 0xb1, 0xe7, 0xb1,
-	0x49, 0xfd, 0xc5, 0x1f, 0xc1, 0x66, 0xeb, 0x8f, 0x70, 0xd9, 0x1f, 0x11, 0x3e, 0x43, 0x98, 0x12,
-	0x6f, 0x3f, 0x51, 0xe2, 0xc5, 0x4c, 0xe2, 0xc1, 0x68, 0x7d, 0x3e, 0x0b, 0xcc, 0xb9, 0x5d, 0xa7,
-	0xdc, 0xae, 0x9a, 0xb5, 0x94, 0xb5, 0x38, 0xe6, 0x03, 0xe3, 0xd6, 0x1d, 0x03, 0x7d, 0x1f, 0x40,
-	0xd6, 0xc5, 0x52, 0x7b, 0x30, 0x59, 0x6b, 0x4b, 0xed, 0xc1, 0x54, 0x49, 0xcd, 0x5c, 0xa4, 0x7c,
-	0x6f, 0x9a, 0xd7, 0x93, 0x7c, 0x43, 0xdf, 0x76, 0x83, 0x97, 0xd8, 0xbf, 0xcd, 0x52, 0xeb, 0xc1,
-	0x9e, 0x33, 0x24, 0x53, 0xf6, 0xa1, 0x18, 0x15, 0x12, 0x92, 0xfe, 0x36, 0x59, 0x60, 0x49, 0xfa,
-	0xdb, 0x54, 0xbd, 0x23, 0xee, 0x78, 0x62, 0xeb, 0x45, 0xa0, 0x92, 0x2d, 0xf8, 0xe7, 0x55, 0x18,
-	0x27, 0x47, 0x72, 0x72, 0x3c, 0x91, 0xe9, 0x9e, 0xe4, 0xec, 0x53, 0x19, 0xeb, 0xe4, 0xec, 0xd3,
-	0x99, 0xa2, 0xf8, 0xf1, 0x84, 0x5c, 0xd7, 0x1a, 0x2c, 0x8f, 0x42, 0x66, 0xea, 0x41, 0x49, 0x49,
-	0x03, 0x21, 0x0d, 0xb1, 0x78, 0x06, 0x3c, 0x19, 0xf0, 0x34, 0x39, 0x24, 0xf3, 0x32, 0xe5, 0x77,
-	0x9e, 0x05, 0x3c, 0xca, 0xaf, 0xcb, 0x30, 0x08, 0x43, 0x3e, 0x3b, 0xbe, 0xf3, 0x35, 0xb3, 0x8b,
-	0xef, 0xfe, 0x85, 0x6c, 0x84, 0xcc, 0xd9, 0xc9, 0xad, 0xff, 0x0a, 0xca, 0x6a, 0xea, 0x07, 0x69,
-	0x84, 0x4f, 0xe4, 0xe8, 0x93, 0x91, 0x44, 0x97, 0x39, 0x8a, 0xfb, 0x36, 0xca, 0xd2, 0x56, 0xd0,
-	0x08, 0xe3, 0x3e, 0x14, 0x78, 0x0a, 0x48, 0xa7, 0xd2, 0x78, 0x1a, 0x5f, 0xa7, 0xd2, 0x44, 0xfe,
-	0x28, 0x7e, 0x7e, 0xa6, 0x1c, 0xc9, 0x55, 0x54, 0x44, 0x6b, 0xce, 0xed, 0x11, 0x0e, 0xb3, 0xb8,
-	0xc9, 0xb4, 0x6d, 0x16, 0x37, 0x25, 0x43, 0x90, 0xc5, 0xad, 0x87, 0x43, 0xee, 0x0f, 0xc4, 0xf5,
-	0x1a, 0x65, 0x10, 0x53, 0x23, 0xa4, 0x79, 0x1c, 0x8a, 0xee, 0x7a, 0x23, 0x19, 0x8a, 0xf0, 0x78,
-	0x08, 0x20, 0xd3, 0x51, 0xc9, 0x33, 0xab, 0xb6, 0x52, 0x90, 0x3c, 0xb3, 0xea, 0x33, 0x5a, 0x71,
-	0x1f, 0x2b, 0xf9, 0xb2, 0xdb, 0x15, 0xe1, 0xfc, 0x85, 0x01, 0x28, 0x9d, 0xb0, 0x42, 0xef, 0xe8,
-	0xa9, 0x6b, 0xab, 0x0e, 0xf5, 0x77, 0x5f, 0x0f, 0x59, 0xe7, 0x90, 0xa5, 0x48, 0x1d, 0x8a, 0x3d,
-	0x7c, 0x45, 0x84, 0xfa, 0xdc, 0x80, 0xe9, 0x58, 0x92, 0x0b, 0xbd, 0x95, 0x61, 0xd3, 0x44, 0xe9,
-	0xa1, 0xfe, 0x8d, 0x13, 0xf1, 0x74, 0x87, 0x79, 0x65, 0x05, 0x88, 0x5b, 0xcd, 0x6f, 0x1b, 0x50,
-	0x89, 0xe7, 0xc2, 0x50, 0x06, 0xed, 0x54, 0xc5, 0xa2, 0x7e, 0xf3, 0x64, 0xc4, 0xe3, 0xcd, 0x23,
-	0x2f, 0x34, 0x7d, 0x28, 0xf0, 0xa4, 0x99, 0x6e, 0xe1, 0xc7, 0x4b, 0x1c, 0xba, 0x85, 0x9f, 0xc8,
-	0xb8, 0x69, 0x16, 0xbe, 0xef, 0xf5, 0xb1, 0xb2, 0xcd, 0x78, 0x2e, 0x2d, 0x8b, 0xdb, 0xf1, 0xdb,
-	0x2c, 0x91, 0x88, 0xcb, 0xe2, 0x26, 0xb7, 0x99, 0x48, 0x99, 0xa1, 0x0c, 0x62, 0x27, 0x6c, 0xb3,
-	0x64, 0xc6, 0x4d, 0xb3, 0xcd, 0x28, 0x43, 0x65, 0x9b, 0xc9, 0x54, 0x96, 0x6e, 0x9b, 0xa5, 0xaa,
-	0x31, 0xba, 0x6d, 0x96, 0xce, 0x86, 0x69, 0xec, 0x48, 0xf9, 0xc6, 0xb6, 0xd9, 0x39, 0x4d, 0xb2,
-	0x0b, 0xbd, 0x9b, 0xa1, 0x44, 0x6d, 0x6d, 0xa7, 0x7e, 0xfb, 0x35, 0xb1, 0x33, 0xd7, 0x38, 0x53,
-	0xbf, 0x58, 0xe3, 0x7f, 0x68, 0xc0, 0x9c, 0x2e, 0x3f, 0x86, 0x32, 0xf8, 0x64, 0x94, 0x82, 0xea,
-	0x8b, 0xaf, 0x8b, 0x7e, 0xbc, 0xb6, 0xa2, 0x55, 0xff, 0xb0, 0xf7, 0x45, 0xb3, 0xf1, 0xe2, 0x1a,
-	0x5c, 0x85, 0xc9, 0xe6, 0xd0, 0x79, 0x82, 0x8f, 0xd0, 0xb9, 0xa9, 0x5c, 0x7d, 0x9a, 0xd0, 0xf5,
-	0x7c, 0xe7, 0x33, 0xfa, 0xc3, 0x12, 0x0b, 0xb9, 0xdd, 0x32, 0x40, 0x84, 0x30, 0xf6, 0xaf, 0x5f,
-	0xce, 0x1b, 0xff, 0xf1, 0xe5, 0xbc, 0xf1, 0xdf, 0x5f, 0xce, 0x1b, 0x3f, 0xfd, 0xdf, 0xf9, 0xb1,
-	0x17, 0xd7, 0x7b, 0x1e, 0x15, 0x6b, 0xd1, 0xf1, 0x1a, 0xf2, 0xc7, 0x2e, 0x96, 0x1b, 0xaa, 0xa8,
-	0xbb, 0x93, 0xf4, 0xd7, 0x29, 0x96, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x97, 0xb0, 0x67, 0xa9,
-	0x74, 0x43, 0x00, 0x00,
+	// 4574 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x3c, 0x5d, 0x6f, 0x1b, 0x57,
+	0x76, 0x1a, 0x92, 0x12, 0xc9, 0xc3, 0x0f, 0xd1, 0xd7, 0xb2, 0x4d, 0xd3, 0xb6, 0xac, 0x8c, 0xed,
+	0xc4, 0x71, 0x62, 0xd1, 0x96, 0xec, 0x64, 0xeb, 0x22, 0xe9, 0xd2, 0x12, 0x63, 0x6b, 0x2d, 0x4b,
+	0xca, 0x88, 0x76, 0x36, 0x2e, 0xb0, 0xea, 0x88, 0xbc, 0xa6, 0x66, 0x45, 0xce, 0x70, 0x67, 0x86,
+	0xb4, 0x94, 0x3e, 0x6c, 0xba, 0xed, 0x76, 0xb1, 0x2d, 0xb0, 0x40, 0x53, 0xa0, 0x58, 0x14, 0xed,
+	0x4b, 0x5b, 0xa0, 0x7d, 0x68, 0x8b, 0xf6, 0xa1, 0x0f, 0x45, 0x0b, 0xf4, 0xa1, 0x7d, 0x68, 0x1f,
+	0x0a, 0x14, 0xe8, 0x1f, 0x68, 0xd3, 0x7d, 0xea, 0xaf, 0x58, 0xdc, 0xaf, 0xb9, 0x77, 0xbe, 0x24,
+	0x67, 0xa5, 0x60, 0x5f, 0x62, 0xce, 0x3d, 0x9f, 0xf7, 0x9c, 0x7b, 0xcf, 0xb9, 0xf7, 0x9c, 0x1b,
+	0x41, 0xd1, 0x1d, 0x75, 0x17, 0x47, 0xae, 0xe3, 0x3b, 0xa8, 0x8c, 0xfd, 0x6e, 0xcf, 0xc3, 0xee,
+	0x04, 0xbb, 0xa3, 0xdd, 0xc6, 0x5c, 0xdf, 0xe9, 0x3b, 0x14, 0xd0, 0x24, 0xbf, 0x18, 0x4e, 0xa3,
+	0x4e, 0x70, 0x9a, 0xe6, 0xc8, 0x6a, 0x0e, 0x27, 0xdd, 0xee, 0x68, 0xb7, 0xb9, 0x3f, 0xe1, 0x90,
+	0x46, 0x00, 0x31, 0xc7, 0xfe, 0xde, 0x68, 0x97, 0xfe, 0xc3, 0x61, 0x0b, 0x01, 0x6c, 0x82, 0x5d,
+	0xcf, 0x72, 0xec, 0xd1, 0xae, 0xf8, 0xc5, 0x31, 0x2e, 0xf7, 0x1d, 0xa7, 0x3f, 0xc0, 0x8c, 0xde,
+	0xb6, 0x1d, 0xdf, 0xf4, 0x2d, 0xc7, 0xf6, 0x38, 0x94, 0xfd, 0xd3, 0xbd, 0xdd, 0xc7, 0xf6, 0x6d,
+	0x67, 0x84, 0x6d, 0x73, 0x64, 0x4d, 0x96, 0x9a, 0xce, 0x88, 0xe2, 0xc4, 0xf1, 0xf5, 0x9f, 0x68,
+	0x50, 0x35, 0xb0, 0x37, 0x72, 0x6c, 0x0f, 0x3f, 0xc6, 0x66, 0x0f, 0xbb, 0xe8, 0x0a, 0x40, 0x77,
+	0x30, 0xf6, 0x7c, 0xec, 0xee, 0x58, 0xbd, 0xba, 0xb6, 0xa0, 0xdd, 0xcc, 0x19, 0x45, 0x3e, 0xb2,
+	0xd6, 0x43, 0x97, 0xa0, 0x38, 0xc4, 0xc3, 0x5d, 0x06, 0xcd, 0x50, 0x68, 0x81, 0x0d, 0xac, 0xf5,
+	0x50, 0x03, 0x0a, 0x2e, 0x9e, 0x58, 0x44, 0xdd, 0x7a, 0x76, 0x41, 0xbb, 0x99, 0x35, 0x82, 0x6f,
+	0x42, 0xe8, 0x9a, 0x2f, 0xfd, 0x1d, 0x1f, 0xbb, 0xc3, 0x7a, 0x8e, 0x11, 0x92, 0x81, 0x0e, 0x76,
+	0x87, 0x0f, 0xf2, 0x3f, 0xf8, 0x87, 0x7a, 0x76, 0x79, 0xf1, 0x8e, 0xfe, 0xaf, 0xd3, 0x50, 0x36,
+	0x4c, 0xbb, 0x8f, 0x0d, 0xfc, 0xbd, 0x31, 0xf6, 0x7c, 0x54, 0x83, 0xec, 0x3e, 0x3e, 0xa4, 0x7a,
+	0x94, 0x0d, 0xf2, 0x93, 0x31, 0xb2, 0xfb, 0x78, 0x07, 0xdb, 0x4c, 0x83, 0x32, 0x61, 0x64, 0xf7,
+	0x71, 0xdb, 0xee, 0xa1, 0x39, 0x98, 0x1e, 0x58, 0x43, 0xcb, 0xe7, 0xe2, 0xd9, 0x47, 0x48, 0xaf,
+	0x5c, 0x44, 0xaf, 0x15, 0x00, 0xcf, 0x71, 0xfd, 0x1d, 0xc7, 0xed, 0x61, 0xb7, 0x3e, 0xbd, 0xa0,
+	0xdd, 0xac, 0x2e, 0x5d, 0x5f, 0x54, 0x3d, 0xbc, 0xa8, 0x2a, 0xb4, 0xb8, 0xed, 0xb8, 0xfe, 0x26,
+	0xc1, 0x35, 0x8a, 0x9e, 0xf8, 0x89, 0x3e, 0x82, 0x12, 0x65, 0xe2, 0x9b, 0x6e, 0x1f, 0xfb, 0xf5,
+	0x19, 0xca, 0xe5, 0xc6, 0x31, 0x5c, 0x3a, 0x14, 0xd9, 0xa0, 0xe2, 0xd9, 0x6f, 0xa4, 0x43, 0xd9,
+	0xc3, 0xae, 0x65, 0x0e, 0xac, 0xcf, 0xcc, 0xdd, 0x01, 0xae, 0xe7, 0x17, 0xb4, 0x9b, 0x05, 0x23,
+	0x34, 0x46, 0xe6, 0xbf, 0x8f, 0x0f, 0xbd, 0x1d, 0xc7, 0x1e, 0x1c, 0xd6, 0x0b, 0x14, 0xa1, 0x40,
+	0x06, 0x36, 0xed, 0xc1, 0x21, 0xf5, 0x9e, 0x33, 0xb6, 0x7d, 0x06, 0x2d, 0x52, 0x68, 0x91, 0x8e,
+	0x50, 0xf0, 0x5d, 0xa8, 0x0d, 0x2d, 0x7b, 0x67, 0xe8, 0xf4, 0x76, 0x02, 0x83, 0x00, 0x31, 0xc8,
+	0xc3, 0xfc, 0xef, 0x51, 0x0f, 0xdc, 0x35, 0xaa, 0x43, 0xcb, 0x7e, 0xea, 0xf4, 0x0c, 0x61, 0x1f,
+	0x42, 0x62, 0x1e, 0x84, 0x49, 0x4a, 0x51, 0x12, 0xf3, 0x40, 0x25, 0x79, 0x1f, 0xce, 0x12, 0x29,
+	0x5d, 0x17, 0x9b, 0x3e, 0x96, 0x54, 0xe5, 0x30, 0xd5, 0x99, 0xa1, 0x65, 0xaf, 0x50, 0x94, 0x10,
+	0xa1, 0x79, 0x10, 0x23, 0xac, 0x44, 0x09, 0xcd, 0x83, 0x30, 0xa1, 0xfe, 0x3e, 0x14, 0x03, 0xbf,
+	0xa0, 0x02, 0xe4, 0x36, 0x36, 0x37, 0xda, 0xb5, 0x29, 0x04, 0x30, 0xd3, 0xda, 0x5e, 0x69, 0x6f,
+	0xac, 0xd6, 0x34, 0x54, 0x82, 0xfc, 0x6a, 0x9b, 0x7d, 0x64, 0x1a, 0xf9, 0x2f, 0xf8, 0x7a, 0x7b,
+	0x02, 0x20, 0x5d, 0x81, 0xf2, 0x90, 0x7d, 0xd2, 0xfe, 0xb4, 0x36, 0x45, 0x90, 0x9f, 0xb7, 0x8d,
+	0xed, 0xb5, 0xcd, 0x8d, 0x9a, 0x46, 0xb8, 0xac, 0x18, 0xed, 0x56, 0xa7, 0x5d, 0xcb, 0x10, 0x8c,
+	0xa7, 0x9b, 0xab, 0xb5, 0x2c, 0x2a, 0xc2, 0xf4, 0xf3, 0xd6, 0xfa, 0xb3, 0x76, 0x2d, 0x17, 0x30,
+	0x93, 0xab, 0xf8, 0x4f, 0x34, 0xa8, 0x70, 0x77, 0xb3, 0xbd, 0x85, 0xee, 0xc1, 0xcc, 0x1e, 0xdd,
+	0x5f, 0x74, 0x25, 0x97, 0x96, 0x2e, 0x47, 0xd6, 0x46, 0x68, 0x0f, 0x1a, 0x1c, 0x17, 0xe9, 0x90,
+	0xdd, 0x9f, 0x78, 0xf5, 0xcc, 0x42, 0xf6, 0x66, 0x69, 0xa9, 0xb6, 0xc8, 0x22, 0xc9, 0xe2, 0x13,
+	0x7c, 0xf8, 0xdc, 0x1c, 0x8c, 0xb1, 0x41, 0x80, 0x08, 0x41, 0x6e, 0xe8, 0xb8, 0x98, 0x2e, 0xf8,
+	0x82, 0x41, 0x7f, 0x93, 0x5d, 0x40, 0x7d, 0xce, 0x17, 0x3b, 0xfb, 0x90, 0xea, 0xfd, 0xa7, 0x06,
+	0xb0, 0x35, 0xf6, 0xd3, 0xb7, 0xd8, 0x1c, 0x4c, 0x4f, 0x88, 0x04, 0xbe, 0xbd, 0xd8, 0x07, 0xdd,
+	0x5b, 0xd8, 0xf4, 0x70, 0xb0, 0xb7, 0xc8, 0x07, 0x5a, 0x80, 0xfc, 0xc8, 0xc5, 0x93, 0x9d, 0xfd,
+	0x09, 0x95, 0x56, 0x90, 0x7e, 0x9a, 0x21, 0xe3, 0x4f, 0x26, 0xe8, 0x16, 0x94, 0xad, 0xbe, 0xed,
+	0xb8, 0x78, 0x87, 0x31, 0x9d, 0x56, 0xd1, 0x96, 0x8c, 0x12, 0x03, 0xd2, 0x29, 0x29, 0xb8, 0x4c,
+	0xd4, 0x4c, 0x22, 0xee, 0x3a, 0x81, 0xc9, 0xf9, 0x7c, 0xae, 0x41, 0x89, 0xce, 0xe7, 0x44, 0xc6,
+	0x5e, 0x92, 0x13, 0xc9, 0x50, 0xb2, 0x98, 0xc1, 0x63, 0x53, 0x93, 0x2a, 0xd8, 0x80, 0x56, 0xf1,
+	0x00, 0xfb, 0xf8, 0x24, 0xc1, 0x4b, 0x31, 0x65, 0x36, 0xd1, 0x94, 0x52, 0xde, 0x5f, 0x68, 0x70,
+	0x36, 0x24, 0xf0, 0x44, 0x53, 0xaf, 0x43, 0xbe, 0x47, 0x99, 0x31, 0x9d, 0xb2, 0x86, 0xf8, 0x44,
+	0xf7, 0xa0, 0xc0, 0x55, 0xf2, 0xea, 0xd9, 0xe4, 0x65, 0x28, 0xb5, 0xcc, 0x33, 0x2d, 0x3d, 0xa9,
+	0xe6, 0x3f, 0x65, 0xa0, 0xc8, 0x8d, 0xb1, 0x39, 0x42, 0x2d, 0xa8, 0xb8, 0xec, 0x63, 0x87, 0xce,
+	0x99, 0xeb, 0xd8, 0x48, 0x8f, 0x93, 0x8f, 0xa7, 0x8c, 0x32, 0x27, 0xa1, 0xc3, 0xe8, 0x57, 0xa1,
+	0x24, 0x58, 0x8c, 0xc6, 0x3e, 0x77, 0x54, 0x3d, 0xcc, 0x40, 0x2e, 0xed, 0xc7, 0x53, 0x06, 0x70,
+	0xf4, 0xad, 0xb1, 0x8f, 0x3a, 0x30, 0x27, 0x88, 0xd9, 0xfc, 0xb8, 0x1a, 0x59, 0xca, 0x65, 0x21,
+	0xcc, 0x25, 0xee, 0xce, 0xc7, 0x53, 0x06, 0xe2, 0xf4, 0x0a, 0x10, 0xad, 0x4a, 0x95, 0xfc, 0x03,
+	0x96, 0x5f, 0x62, 0x2a, 0x75, 0x0e, 0x6c, 0xce, 0x44, 0x58, 0x6b, 0x59, 0xd1, 0xad, 0x73, 0x60,
+	0x07, 0x26, 0x7b, 0x58, 0x84, 0x3c, 0x1f, 0xd6, 0xff, 0x23, 0x03, 0x20, 0x3c, 0xb6, 0x39, 0x42,
+	0xab, 0x50, 0x75, 0xf9, 0x57, 0xc8, 0x7e, 0x97, 0x12, 0xed, 0xc7, 0x1d, 0x3d, 0x65, 0x54, 0x04,
+	0x11, 0x53, 0xf7, 0x43, 0x28, 0x07, 0x5c, 0xa4, 0x09, 0x2f, 0x26, 0x98, 0x30, 0xe0, 0x50, 0x12,
+	0x04, 0xc4, 0x88, 0x9f, 0xc0, 0xb9, 0x80, 0x3e, 0xc1, 0x8a, 0x6f, 0x1c, 0x61, 0xc5, 0x80, 0xe1,
+	0x59, 0xc1, 0x41, 0xb5, 0xe3, 0x23, 0x45, 0x31, 0x69, 0xc8, 0x8b, 0x09, 0x86, 0x64, 0x48, 0xaa,
+	0x25, 0x03, 0x0d, 0x43, 0xa6, 0x04, 0x92, 0xf6, 0xd9, 0xb8, 0xfe, 0x57, 0x39, 0xc8, 0xaf, 0x38,
+	0xc3, 0x91, 0xe9, 0x92, 0x45, 0x34, 0xe3, 0x62, 0x6f, 0x3c, 0xf0, 0xa9, 0x01, 0xab, 0x4b, 0xd7,
+	0xc2, 0x32, 0x38, 0x9a, 0xf8, 0xd7, 0xa0, 0xa8, 0x06, 0x27, 0x21, 0xc4, 0x3c, 0xcb, 0x67, 0x5e,
+	0x83, 0x98, 0xe7, 0x78, 0x4e, 0x22, 0x02, 0x42, 0x56, 0x06, 0x84, 0x06, 0xe4, 0xf9, 0x01, 0x8f,
+	0x05, 0xeb, 0xc7, 0x53, 0x86, 0x18, 0x40, 0x6f, 0xc3, 0x6c, 0x34, 0x15, 0x4e, 0x73, 0x9c, 0x6a,
+	0x37, 0x9c, 0x39, 0xaf, 0x41, 0x39, 0x94, 0xa1, 0x67, 0x38, 0x5e, 0x69, 0xa8, 0xe4, 0xe5, 0xf3,
+	0x22, 0xac, 0x93, 0x63, 0x45, 0xf9, 0xf1, 0x94, 0x08, 0xec, 0x57, 0x45, 0x60, 0x2f, 0xa8, 0x89,
+	0x96, 0xd8, 0x95, 0xc7, 0xf8, 0xeb, 0x6a, 0xd4, 0xfa, 0x26, 0x21, 0x0e, 0x90, 0x64, 0xf8, 0xd2,
+	0x0d, 0xa8, 0x84, 0x4c, 0x46, 0x72, 0x64, 0xfb, 0xe3, 0x67, 0xad, 0x75, 0x96, 0x50, 0x1f, 0xd1,
+	0x1c, 0x6a, 0xd4, 0x34, 0x92, 0xa0, 0xd7, 0xdb, 0xdb, 0xdb, 0xb5, 0x0c, 0x3a, 0x0f, 0xc5, 0x8d,
+	0xcd, 0xce, 0x0e, 0xc3, 0xca, 0x36, 0xf2, 0x7f, 0xcc, 0x22, 0x89, 0xcc, 0xcf, 0x9f, 0x06, 0x3c,
+	0x79, 0x8a, 0x56, 0x32, 0xf3, 0x94, 0x92, 0x99, 0x35, 0x91, 0x99, 0x33, 0x32, 0x33, 0x67, 0x11,
+	0x82, 0xe9, 0xf5, 0x76, 0x6b, 0x9b, 0x26, 0x69, 0xc6, 0x7a, 0x39, 0x9e, 0xad, 0x1f, 0x56, 0xa1,
+	0xcc, 0xdc, 0xb3, 0x33, 0xb6, 0xc9, 0x61, 0xe2, 0xaf, 0x35, 0x00, 0xb9, 0x61, 0x51, 0x13, 0xf2,
+	0x5d, 0xa6, 0x42, 0x5d, 0xa3, 0x11, 0xf0, 0x5c, 0xa2, 0xc7, 0x0d, 0x81, 0x85, 0xee, 0x42, 0xde,
+	0x1b, 0x77, 0xbb, 0xd8, 0x13, 0x99, 0xfb, 0x42, 0x34, 0x08, 0xf3, 0x80, 0x68, 0x08, 0x3c, 0x42,
+	0xf2, 0xd2, 0xb4, 0x06, 0x63, 0x9a, 0xc7, 0x8f, 0x26, 0xe1, 0x78, 0x32, 0xc6, 0xfe, 0x99, 0x06,
+	0x25, 0x65, 0x5b, 0xfc, 0x82, 0x29, 0xe0, 0x32, 0x14, 0xa9, 0x32, 0xb8, 0xc7, 0x93, 0x40, 0xc1,
+	0x90, 0x03, 0xe8, 0x3d, 0x28, 0x8a, 0x9d, 0x24, 0xf2, 0x40, 0x3d, 0x99, 0xed, 0xe6, 0xc8, 0x90,
+	0xa8, 0x52, 0xc9, 0x0e, 0x9c, 0xa1, 0x76, 0xea, 0x92, 0xdb, 0x87, 0xb0, 0xac, 0x7a, 0x2c, 0xd7,
+	0x22, 0xc7, 0xf2, 0x06, 0x14, 0x46, 0x7b, 0x87, 0x9e, 0xd5, 0x35, 0x07, 0x5c, 0x9d, 0xe0, 0x5b,
+	0x72, 0xdd, 0x06, 0xa4, 0x72, 0x3d, 0x89, 0x01, 0x24, 0xd3, 0xf3, 0x50, 0x7a, 0x6c, 0x7a, 0x7b,
+	0x5c, 0x49, 0x39, 0x7e, 0x0f, 0x2a, 0x64, 0xfc, 0xc9, 0xf3, 0xd7, 0x50, 0x5f, 0x50, 0x2d, 0xeb,
+	0xff, 0xac, 0x41, 0x55, 0x90, 0x9d, 0xc8, 0x41, 0x08, 0x72, 0x7b, 0xa6, 0xb7, 0x47, 0x8d, 0x51,
+	0x31, 0xe8, 0x6f, 0xf4, 0x36, 0xd4, 0xba, 0x6c, 0xfe, 0x3b, 0x91, 0x7b, 0xd7, 0x2c, 0x1f, 0x0f,
+	0xf6, 0xfe, 0xbb, 0x50, 0x21, 0x24, 0x3b, 0xe1, 0x7b, 0x90, 0xd8, 0xc6, 0xef, 0x19, 0xe5, 0x3d,
+	0x3a, 0xe7, 0xa8, 0xfa, 0x26, 0x94, 0x99, 0x31, 0x4e, 0x5b, 0x77, 0x69, 0xd7, 0x06, 0xcc, 0x6e,
+	0xdb, 0xe6, 0xc8, 0xdb, 0x73, 0xfc, 0x88, 0xcd, 0x97, 0xf5, 0xbf, 0xd7, 0xa0, 0x26, 0x81, 0x27,
+	0xd2, 0xe1, 0x2d, 0x98, 0x75, 0xf1, 0xd0, 0xb4, 0x6c, 0xcb, 0xee, 0xef, 0xec, 0x1e, 0xfa, 0xd8,
+	0xe3, 0xd7, 0xd7, 0x6a, 0x30, 0xfc, 0x90, 0x8c, 0x12, 0x65, 0x77, 0x07, 0xce, 0x2e, 0x0f, 0xd2,
+	0xf4, 0x37, 0x7a, 0x23, 0x1c, 0xa5, 0x8b, 0xd2, 0x6e, 0x62, 0x5c, 0xea, 0xfc, 0xd3, 0x0c, 0x94,
+	0x3f, 0x31, 0xfd, 0xae, 0x58, 0x41, 0x68, 0x0d, 0xaa, 0x41, 0x18, 0xa7, 0x23, 0x5c, 0xef, 0xc8,
+	0x81, 0x83, 0xd2, 0x88, 0x7b, 0x8d, 0x38, 0x70, 0x54, 0xba, 0xea, 0x00, 0x65, 0x65, 0xda, 0x5d,
+	0x3c, 0x08, 0x58, 0x65, 0xd2, 0x59, 0x51, 0x44, 0x95, 0x95, 0x3a, 0x80, 0xbe, 0x0d, 0xb5, 0x91,
+	0xeb, 0xf4, 0x5d, 0xec, 0x79, 0x01, 0x33, 0x96, 0xc2, 0xf5, 0x04, 0x66, 0x5b, 0x1c, 0x35, 0x72,
+	0x8a, 0xb9, 0xf7, 0x78, 0xca, 0x98, 0x1d, 0x85, 0x61, 0x32, 0xb0, 0xce, 0xca, 0xf3, 0x1e, 0x8b,
+	0xac, 0x3f, 0xca, 0x02, 0x8a, 0x4f, 0xf3, 0xab, 0x1e, 0x93, 0x6f, 0x40, 0xd5, 0xf3, 0x4d, 0x37,
+	0xb6, 0xe6, 0x2b, 0x74, 0x34, 0x58, 0xf1, 0x6f, 0x41, 0xa0, 0xd9, 0x8e, 0xed, 0xf8, 0xd6, 0xcb,
+	0x43, 0x76, 0x41, 0x31, 0xaa, 0x62, 0x78, 0x83, 0x8e, 0xa2, 0x0d, 0xc8, 0xbf, 0xb4, 0x06, 0x3e,
+	0x76, 0xbd, 0xfa, 0xf4, 0x42, 0xf6, 0x66, 0x75, 0xe9, 0x9d, 0xe3, 0x1c, 0xb3, 0xf8, 0x11, 0xc5,
+	0xef, 0x1c, 0x8e, 0xd4, 0xd3, 0x2f, 0x67, 0xa2, 0x1e, 0xe3, 0x67, 0x92, 0x6f, 0x44, 0x3a, 0x14,
+	0x5e, 0x11, 0xa6, 0x3b, 0x56, 0x8f, 0xe6, 0xe2, 0x60, 0x1f, 0xde, 0x33, 0xf2, 0x14, 0xb0, 0xd6,
+	0x43, 0xd7, 0xa0, 0xf0, 0xd2, 0x35, 0xfb, 0x43, 0x6c, 0xfb, 0xec, 0x96, 0x2f, 0x71, 0x02, 0x80,
+	0xbe, 0x08, 0x20, 0x55, 0x21, 0x99, 0x6f, 0x63, 0x73, 0xeb, 0x59, 0xa7, 0x36, 0x85, 0xca, 0x50,
+	0xd8, 0xd8, 0x5c, 0x6d, 0xaf, 0xb7, 0x49, 0x6e, 0x14, 0x39, 0xef, 0xae, 0xdc, 0x74, 0x2d, 0xe1,
+	0x88, 0xd0, 0x9a, 0x50, 0xf5, 0xd2, 0xc2, 0x97, 0x6e, 0xa1, 0x97, 0x60, 0x71, 0x57, 0xbf, 0x0a,
+	0x73, 0x49, 0x4b, 0x43, 0x20, 0xdc, 0xd3, 0xff, 0x2d, 0x03, 0x15, 0xbe, 0x11, 0x4e, 0xb4, 0x73,
+	0x2f, 0x2a, 0x5a, 0xf1, 0xeb, 0x89, 0x30, 0x52, 0x1d, 0xf2, 0x6c, 0x83, 0xf4, 0xf8, 0xfd, 0x57,
+	0x7c, 0x92, 0xe0, 0xcc, 0xd6, 0x3b, 0xee, 0x71, 0xb7, 0x07, 0xdf, 0x89, 0x61, 0x73, 0x3a, 0x35,
+	0x6c, 0x06, 0x1b, 0xce, 0xf4, 0xf8, 0xc1, 0xaa, 0x28, 0x5d, 0x51, 0x16, 0x9b, 0x8a, 0x00, 0x43,
+	0x3e, 0xcb, 0xa7, 0xf8, 0x0c, 0xdd, 0x80, 0x19, 0x3c, 0xc1, 0xb6, 0xef, 0xd5, 0x4b, 0x34, 0x91,
+	0x56, 0xc4, 0x85, 0xaa, 0x4d, 0x46, 0x0d, 0x0e, 0x94, 0xae, 0xfa, 0x10, 0xce, 0xd0, 0xfb, 0xee,
+	0x23, 0xd7, 0xb4, 0xd5, 0x3b, 0x7b, 0xa7, 0xb3, 0xce, 0xd3, 0x0e, 0xf9, 0x89, 0xaa, 0x90, 0x59,
+	0x5b, 0xe5, 0xf6, 0xc9, 0xac, 0xad, 0x4a, 0xfa, 0xdf, 0xd7, 0x00, 0xa9, 0x0c, 0x4e, 0xe4, 0x8b,
+	0x88, 0x14, 0xa1, 0x47, 0x56, 0xea, 0x31, 0x07, 0xd3, 0xd8, 0x75, 0x1d, 0x97, 0x05, 0x4a, 0x83,
+	0x7d, 0x48, 0x6d, 0x6e, 0x73, 0x65, 0x0c, 0x3c, 0x71, 0xf6, 0x83, 0x08, 0xc0, 0xd8, 0x6a, 0x71,
+	0xe5, 0x3b, 0x70, 0x36, 0x84, 0x7e, 0x3a, 0x29, 0x7e, 0x13, 0x66, 0x29, 0xd7, 0x95, 0x3d, 0xdc,
+	0xdd, 0x1f, 0x39, 0x96, 0x1d, 0xd3, 0x00, 0x5d, 0x23, 0xb1, 0x4b, 0xa4, 0x0b, 0x32, 0x45, 0x36,
+	0xe7, 0x72, 0x30, 0xd8, 0xe9, 0xac, 0xcb, 0xa5, 0xbe, 0x0b, 0xe7, 0x23, 0x0c, 0xc5, 0xcc, 0x7e,
+	0x0d, 0x4a, 0xdd, 0x60, 0xd0, 0xe3, 0x27, 0xc8, 0x2b, 0x61, 0x75, 0xa3, 0xa4, 0x2a, 0x85, 0x94,
+	0xf1, 0x6d, 0xb8, 0x10, 0x93, 0x71, 0x1a, 0xe6, 0xb8, 0xa7, 0xdf, 0x81, 0x73, 0x94, 0xf3, 0x13,
+	0x8c, 0x47, 0xad, 0x81, 0x35, 0x39, 0xde, 0x2d, 0x87, 0x7c, 0xbe, 0x0a, 0xc5, 0xd7, 0xbb, 0xac,
+	0xa4, 0xe8, 0x36, 0x17, 0xdd, 0xb1, 0x86, 0xb8, 0xe3, 0xac, 0xa7, 0x6b, 0x4b, 0x12, 0xf9, 0x3e,
+	0x3e, 0xf4, 0xf8, 0xf1, 0x91, 0xfe, 0x96, 0xd1, 0xeb, 0x6f, 0x35, 0x6e, 0x4e, 0x95, 0xcf, 0xd7,
+	0xbc, 0x35, 0xe6, 0x01, 0xfa, 0x64, 0x0f, 0xe2, 0x1e, 0x01, 0xb0, 0xda, 0x9c, 0x32, 0x12, 0x28,
+	0x4c, 0xb2, 0x50, 0x39, 0xaa, 0xf0, 0x15, 0xbe, 0x71, 0xe8, 0x7f, 0xbc, 0xd8, 0x49, 0xe9, 0x4d,
+	0x28, 0x51, 0xc8, 0xb6, 0x6f, 0xfa, 0x63, 0x2f, 0xcd, 0x73, 0xcb, 0xfa, 0x8f, 0x34, 0xbe, 0xa3,
+	0x04, 0x9f, 0x13, 0xcd, 0xf9, 0x2e, 0xcc, 0xd0, 0x1b, 0xa2, 0xb8, 0xe9, 0x5c, 0x4c, 0x58, 0xd8,
+	0x4c, 0x23, 0x83, 0x23, 0x2a, 0xe7, 0x24, 0x0d, 0x66, 0x9e, 0xd2, 0xce, 0x81, 0xa2, 0x6d, 0x4e,
+	0x78, 0xce, 0x36, 0x87, 0xac, 0xfc, 0x58, 0x34, 0xe8, 0x6f, 0x7a, 0x21, 0xc0, 0xd8, 0x7d, 0x66,
+	0xac, 0xb3, 0x1b, 0x48, 0xd1, 0x08, 0xbe, 0x89, 0x61, 0xbb, 0x03, 0x0b, 0xdb, 0x3e, 0x85, 0xe6,
+	0x28, 0x54, 0x19, 0x41, 0x37, 0xa0, 0x68, 0x79, 0xeb, 0xd8, 0x74, 0x6d, 0x5e, 0xe2, 0x57, 0x02,
+	0xb3, 0x84, 0xc8, 0x35, 0xf6, 0x1d, 0xa8, 0x31, 0xcd, 0x5a, 0xbd, 0x9e, 0x72, 0xda, 0x0f, 0xe4,
+	0x6b, 0x11, 0xf9, 0x21, 0xfe, 0x99, 0xe3, 0xf9, 0xff, 0x9d, 0x06, 0x67, 0x14, 0x01, 0x27, 0x72,
+	0xc1, 0xbb, 0x30, 0xc3, 0xfa, 0x2f, 0xfc, 0x28, 0x38, 0x17, 0xa6, 0x62, 0x62, 0x0c, 0x8e, 0x83,
+	0x16, 0x21, 0xcf, 0x7e, 0x89, 0x6b, 0x5c, 0x32, 0xba, 0x40, 0x92, 0x2a, 0x2f, 0xc2, 0x59, 0x0e,
+	0xc3, 0x43, 0x27, 0x69, 0xcf, 0xe5, 0xc2, 0x11, 0xe2, 0x87, 0x1a, 0xcc, 0x85, 0x09, 0x4e, 0x34,
+	0x4b, 0x45, 0xef, 0xcc, 0x57, 0xd2, 0xfb, 0x5b, 0x42, 0xef, 0x67, 0xa3, 0x9e, 0x72, 0xe4, 0x8c,
+	0xae, 0x38, 0xd5, 0xbb, 0x99, 0xb0, 0x77, 0x25, 0xaf, 0x9f, 0x04, 0x73, 0x12, 0xcc, 0x4e, 0x34,
+	0xa7, 0xf7, 0x5f, 0x6b, 0x4e, 0xca, 0x11, 0x2c, 0x36, 0xb9, 0x35, 0xb1, 0x8c, 0xd6, 0x2d, 0x2f,
+	0xc8, 0x38, 0xef, 0x40, 0x79, 0x60, 0xd9, 0xd8, 0x74, 0x79, 0x0f, 0x49, 0x53, 0xd7, 0xe3, 0x7d,
+	0x23, 0x04, 0x94, 0xac, 0x7e, 0x5b, 0x03, 0xa4, 0xf2, 0xfa, 0xe5, 0x78, 0xab, 0x29, 0x0c, 0xbc,
+	0xe5, 0x3a, 0x43, 0xc7, 0x3f, 0x6e, 0x99, 0xdd, 0xd3, 0x7f, 0x57, 0x83, 0x73, 0x11, 0x8a, 0x5f,
+	0x86, 0xe6, 0xf7, 0xf4, 0xcb, 0x70, 0x66, 0x15, 0x8b, 0x33, 0x5e, 0xac, 0x76, 0xb0, 0x0d, 0x48,
+	0x85, 0x9e, 0xce, 0x29, 0xe6, 0x1b, 0x70, 0xe6, 0xa9, 0x33, 0x21, 0x81, 0x9c, 0x80, 0x65, 0x98,
+	0x62, 0xc5, 0xac, 0xc0, 0x5e, 0xc1, 0xb7, 0x0c, 0xbd, 0xdb, 0x80, 0x54, 0xca, 0xd3, 0x50, 0x67,
+	0x59, 0xff, 0x5f, 0x0d, 0xca, 0xad, 0x81, 0xe9, 0x0e, 0x85, 0x2a, 0x1f, 0xc2, 0x0c, 0xab, 0xcc,
+	0xf0, 0x32, 0xeb, 0x9b, 0x61, 0x7e, 0x2a, 0x2e, 0xfb, 0x68, 0xb1, 0x3a, 0x0e, 0xa7, 0x22, 0x53,
+	0xe1, 0x9d, 0xe5, 0xd5, 0x48, 0xa7, 0x79, 0x15, 0xdd, 0x86, 0x69, 0x93, 0x90, 0xd0, 0xf4, 0x5a,
+	0x8d, 0x96, 0xcb, 0x28, 0x37, 0x72, 0x25, 0x32, 0x18, 0x96, 0xfe, 0x01, 0x94, 0x14, 0x09, 0x28,
+	0x0f, 0xd9, 0x47, 0x6d, 0x7e, 0x4d, 0x6a, 0xad, 0x74, 0xd6, 0x9e, 0xb3, 0x12, 0x62, 0x15, 0x60,
+	0xb5, 0x1d, 0x7c, 0x67, 0x12, 0x1a, 0x7b, 0x26, 0xe7, 0xc3, 0xf3, 0x96, 0xaa, 0xa1, 0x96, 0xa6,
+	0x61, 0xe6, 0x75, 0x34, 0x94, 0x22, 0x7e, 0x4b, 0x83, 0x0a, 0x37, 0xcd, 0x49, 0x53, 0x33, 0xe5,
+	0x9c, 0x92, 0x9a, 0x95, 0x69, 0x18, 0x1c, 0x51, 0xea, 0xf0, 0x2f, 0x1a, 0xd4, 0x56, 0x9d, 0x57,
+	0x76, 0xdf, 0x35, 0x7b, 0xc1, 0x1e, 0xfc, 0x28, 0xe2, 0xce, 0xc5, 0x48, 0xa5, 0x3f, 0x82, 0x2f,
+	0x07, 0x22, 0x6e, 0xad, 0xcb, 0x5a, 0x0a, 0xcb, 0xef, 0xe2, 0x53, 0xff, 0x26, 0xcc, 0x46, 0x88,
+	0x88, 0x83, 0x9e, 0xb7, 0xd6, 0xd7, 0x56, 0x89, 0x43, 0x68, 0xbd, 0xb7, 0xbd, 0xd1, 0x7a, 0xb8,
+	0xde, 0xe6, 0x5d, 0xd9, 0xd6, 0xc6, 0x4a, 0x7b, 0x5d, 0x3a, 0xea, 0xbe, 0x98, 0xc1, 0x7d, 0x7d,
+	0x00, 0x67, 0x14, 0x85, 0x4e, 0xda, 0x1c, 0x4b, 0xd6, 0x57, 0x4a, 0xfb, 0x06, 0x5c, 0x0a, 0xa4,
+	0x3d, 0x67, 0xc0, 0x0e, 0xf6, 0xd4, 0xcb, 0xda, 0x84, 0x0b, 0x2d, 0x1a, 0xe4, 0xa7, 0xa0, 0x7c,
+	0x4f, 0xaf, 0x43, 0x85, 0x9f, 0x8f, 0xa2, 0x21, 0xe3, 0xcf, 0x73, 0x50, 0x15, 0xa0, 0xaf, 0x47,
+	0x7f, 0x74, 0x1e, 0x66, 0x7a, 0xbb, 0xdb, 0xd6, 0x67, 0xa2, 0xa3, 0xcb, 0xbf, 0xc8, 0xf8, 0x80,
+	0xc9, 0x61, 0xef, 0x34, 0xf8, 0x17, 0xba, 0xcc, 0x9e, 0x70, 0xac, 0xd9, 0x3d, 0x7c, 0x40, 0x8f,
+	0x51, 0x39, 0x43, 0x0e, 0xd0, 0x72, 0x28, 0x7f, 0xcf, 0x41, 0x6f, 0xc9, 0xca, 0xfb, 0x0e, 0xb4,
+	0x0c, 0x35, 0xf2, 0xbb, 0x35, 0x1a, 0x0d, 0x2c, 0xdc, 0x63, 0x0c, 0xc8, 0x05, 0x39, 0x27, 0xcf,
+	0x49, 0x31, 0x04, 0x74, 0x15, 0x66, 0xe8, 0xe5, 0xd1, 0xab, 0x17, 0x48, 0x46, 0x96, 0xa8, 0x7c,
+	0x18, 0xbd, 0x0d, 0x25, 0xa6, 0xf1, 0x9a, 0xfd, 0xcc, 0xc3, 0xf4, 0xb5, 0x83, 0x52, 0x49, 0x51,
+	0x61, 0xe1, 0x13, 0x1a, 0xa4, 0x9d, 0xd0, 0x50, 0x13, 0xaa, 0x9e, 0xef, 0xb8, 0x66, 0x5f, 0xb8,
+	0x91, 0x3e, 0x75, 0x50, 0xca, 0x7d, 0x11, 0xb0, 0x54, 0xe1, 0xe3, 0xb1, 0xe3, 0x9b, 0xe1, 0x27,
+	0x0e, 0xef, 0x19, 0x2a, 0x0c, 0x7d, 0x0b, 0x2a, 0x3d, 0xb1, 0x48, 0xd6, 0xec, 0x97, 0x0e, 0x7d,
+	0xd6, 0x10, 0xeb, 0xde, 0xad, 0xaa, 0x28, 0x92, 0x53, 0x98, 0x54, 0xbd, 0xc9, 0x56, 0x42, 0x14,
+	0xc4, 0xdb, 0xd8, 0x26, 0xa9, 0x9d, 0x55, 0x70, 0x0a, 0x86, 0xf8, 0x44, 0xd7, 0xa1, 0xc2, 0x32,
+	0xc1, 0xf3, 0xd0, 0x6a, 0x08, 0x0f, 0x92, 0x3c, 0xd6, 0x1a, 0xfb, 0x7b, 0x6d, 0x4a, 0x14, 0x5b,
+	0x94, 0x57, 0x00, 0x11, 0xe8, 0xaa, 0xe5, 0x25, 0x82, 0x39, 0x71, 0xe2, 0x8a, 0xbe, 0xaf, 0x6f,
+	0xc0, 0x59, 0x02, 0xc5, 0xb6, 0x6f, 0x75, 0x95, 0xa3, 0x98, 0x38, 0xec, 0x6b, 0x91, 0xc3, 0xbe,
+	0xe9, 0x79, 0xaf, 0x1c, 0xb7, 0xc7, 0xd5, 0x0c, 0xbe, 0xa5, 0xb4, 0x7f, 0xd4, 0x98, 0x36, 0xcf,
+	0xbc, 0xd0, 0x41, 0xfd, 0x2b, 0xf2, 0x43, 0xbf, 0x02, 0x79, 0xfe, 0x40, 0x8a, 0xd7, 0x3f, 0xcf,
+	0x2f, 0xb2, 0x87, 0x59, 0x8b, 0x9c, 0xf1, 0x26, 0x83, 0x2a, 0x35, 0x3a, 0x8e, 0x4f, 0x96, 0xcb,
+	0x9e, 0xe9, 0xed, 0xe1, 0xde, 0x96, 0x60, 0x1e, 0xaa, 0x0e, 0xdf, 0x37, 0x22, 0x60, 0xa9, 0xfb,
+	0x5d, 0xa9, 0xfa, 0x23, 0xec, 0x1f, 0xa1, 0xba, 0xda, 0x7f, 0x38, 0x27, 0x48, 0x78, 0xdb, 0xf4,
+	0x75, 0xa8, 0x7e, 0xac, 0xc1, 0x15, 0x41, 0xb6, 0xb2, 0x67, 0xda, 0x7d, 0x2c, 0x94, 0xf9, 0x45,
+	0xed, 0x15, 0x9f, 0x74, 0xf6, 0x35, 0x27, 0xfd, 0x04, 0xea, 0xc1, 0xa4, 0x69, 0x2d, 0xca, 0x19,
+	0xa8, 0x93, 0x18, 0x7b, 0x41, 0x90, 0xa4, 0xbf, 0xc9, 0x98, 0xeb, 0x0c, 0x82, 0x6b, 0x20, 0xf9,
+	0x2d, 0x99, 0xad, 0xc3, 0x45, 0xc1, 0x8c, 0x17, 0x87, 0xc2, 0xdc, 0x62, 0x73, 0x3a, 0x92, 0x1b,
+	0xf7, 0x07, 0xe1, 0x71, 0xf4, 0x52, 0x4a, 0x24, 0x09, 0xbb, 0x90, 0x4a, 0xd1, 0x92, 0xa4, 0xcc,
+	0xb3, 0x1d, 0x40, 0x74, 0x56, 0x4e, 0xec, 0x31, 0x38, 0x61, 0x99, 0x08, 0xe7, 0x4b, 0x80, 0xc0,
+	0x63, 0x4b, 0x20, 0x5d, 0x2a, 0x86, 0xf9, 0x40, 0x51, 0x62, 0xf6, 0x2d, 0xec, 0x0e, 0x2d, 0xcf,
+	0x53, 0x1a, 0x71, 0x49, 0xe6, 0x7a, 0x13, 0x72, 0x23, 0xcc, 0x8f, 0x2f, 0xa5, 0x25, 0x24, 0xf6,
+	0x84, 0x42, 0x4c, 0xe1, 0x52, 0xcc, 0x10, 0xae, 0x0a, 0x31, 0xcc, 0x21, 0x89, 0x72, 0xa2, 0x6a,
+	0x8a, 0xe2, 0x7f, 0x26, 0xa5, 0xf8, 0x9f, 0x0d, 0x17, 0xff, 0x43, 0x47, 0x6a, 0x35, 0x50, 0x9d,
+	0xce, 0x91, 0xba, 0xc3, 0x1c, 0x10, 0xc4, 0xb7, 0xd3, 0xe1, 0xfa, 0x07, 0x3c, 0x50, 0x9d, 0x56,
+	0x3a, 0x17, 0x01, 0x3e, 0x13, 0x0e, 0xf0, 0x3a, 0x94, 0x89, 0x93, 0x0c, 0xb5, 0x2b, 0x92, 0x33,
+	0x42, 0x63, 0x32, 0x18, 0xef, 0xc3, 0x5c, 0x38, 0x18, 0x9f, 0x48, 0xa9, 0x39, 0x98, 0xf6, 0x9d,
+	0x7d, 0x2c, 0x72, 0x0a, 0xfb, 0x88, 0x99, 0x35, 0x08, 0xd4, 0xa7, 0x63, 0xd6, 0xef, 0x4a, 0xae,
+	0x74, 0x03, 0x9e, 0x74, 0x06, 0x64, 0x39, 0x8a, 0xdb, 0x3f, 0xfb, 0x90, 0xb2, 0x3e, 0x81, 0xf3,
+	0xd1, 0xe0, 0x7b, 0x3a, 0x93, 0xd8, 0x61, 0x9b, 0x33, 0x29, 0x3c, 0x9f, 0x8e, 0x80, 0x17, 0x32,
+	0x4e, 0x2a, 0x41, 0xf7, 0x74, 0x78, 0xff, 0x3a, 0x34, 0x92, 0x62, 0xf0, 0xa9, 0xee, 0xc5, 0x20,
+	0x24, 0x9f, 0x0e, 0xd7, 0x1f, 0x6a, 0x92, 0xad, 0xba, 0x6a, 0x3e, 0xf8, 0x2a, 0x6c, 0x45, 0xae,
+	0xbb, 0x13, 0x2c, 0x9f, 0x66, 0x10, 0x2d, 0xb3, 0xc9, 0xd1, 0x52, 0x92, 0x50, 0x44, 0xb1, 0xff,
+	0x64, 0xa8, 0xff, 0x3a, 0x57, 0x2f, 0x17, 0x26, 0xf3, 0xce, 0x49, 0x85, 0x91, 0xf4, 0x1c, 0x08,
+	0xa3, 0x1f, 0xb1, 0xad, 0xa2, 0x26, 0xa9, 0xd3, 0x71, 0xdd, 0x6f, 0xc8, 0x04, 0x13, 0xcb, 0x63,
+	0xa7, 0x23, 0xc1, 0x84, 0x85, 0xf4, 0x14, 0x76, 0x2a, 0x22, 0x6e, 0xb5, 0xa0, 0x18, 0xdc, 0xfd,
+	0x95, 0x97, 0xca, 0x25, 0xc8, 0x6f, 0x6c, 0x6e, 0x6f, 0xb5, 0x56, 0xc8, 0xd5, 0x76, 0x0e, 0xf2,
+	0x2b, 0x9b, 0x86, 0xf1, 0x6c, 0xab, 0x43, 0xee, 0xb6, 0xd1, 0x87, 0x4b, 0x4b, 0x3f, 0xcb, 0x42,
+	0xe6, 0xc9, 0x73, 0xf4, 0x29, 0x4c, 0xb3, 0x87, 0x73, 0x47, 0xbc, 0x9f, 0x6c, 0x1c, 0xf5, 0x36,
+	0x50, 0xbf, 0xf0, 0x83, 0xff, 0xfe, 0xd9, 0x1f, 0x66, 0xce, 0xe8, 0xe5, 0xe6, 0x64, 0xb9, 0xb9,
+	0x3f, 0x69, 0xd2, 0x24, 0xfb, 0x40, 0xbb, 0x85, 0x3e, 0x86, 0xec, 0xd6, 0xd8, 0x47, 0xa9, 0xef,
+	0x2a, 0x1b, 0xe9, 0xcf, 0x05, 0xf5, 0x73, 0x94, 0xe9, 0xac, 0x0e, 0x9c, 0xe9, 0x68, 0xec, 0x13,
+	0x96, 0xdf, 0x83, 0x92, 0xfa, 0xd8, 0xef, 0xd8, 0xc7, 0x96, 0x8d, 0xe3, 0x1f, 0x12, 0xea, 0x57,
+	0xa8, 0xa8, 0x0b, 0x3a, 0xe2, 0xa2, 0xd8, 0x73, 0x44, 0x75, 0x16, 0x9d, 0x03, 0x1b, 0xa5, 0x3e,
+	0xc5, 0x6c, 0xa4, 0xbf, 0x2d, 0x8c, 0xcd, 0xc2, 0x3f, 0xb0, 0x09, 0xcb, 0xef, 0xf2, 0x47, 0x84,
+	0x5d, 0x1f, 0x5d, 0x4d, 0x78, 0x05, 0xa6, 0xbe, 0x6e, 0x6a, 0x2c, 0xa4, 0x23, 0x70, 0x21, 0x97,
+	0xa9, 0x90, 0xf3, 0xfa, 0x19, 0x2e, 0xa4, 0x1b, 0xa0, 0x3c, 0xd0, 0x6e, 0x2d, 0x75, 0x61, 0x9a,
+	0x76, 0xcf, 0xd1, 0x0b, 0xf1, 0xa3, 0x91, 0xf0, 0x2e, 0x21, 0xc5, 0xd1, 0xa1, 0xbe, 0xbb, 0x3e,
+	0x47, 0x05, 0x55, 0xf5, 0x22, 0x11, 0x44, 0x7b, 0xe7, 0x0f, 0xb4, 0x5b, 0x37, 0xb5, 0x3b, 0xda,
+	0xd2, 0xdf, 0x4c, 0xc3, 0x34, 0xed, 0xd2, 0xa0, 0x7d, 0x00, 0xd9, 0x25, 0x8e, 0xce, 0x2e, 0xd6,
+	0x80, 0x8e, 0xce, 0x2e, 0xde, 0x60, 0xd6, 0x1b, 0x54, 0xe8, 0x9c, 0x3e, 0x4b, 0x84, 0xd2, 0xe6,
+	0x4f, 0x93, 0xf6, 0xba, 0x88, 0x1d, 0x7f, 0xac, 0xf1, 0x76, 0x15, 0xdb, 0x66, 0x28, 0x89, 0x5b,
+	0xa8, 0x43, 0x1c, 0x5d, 0x0e, 0x09, 0x4d, 0x61, 0xfd, 0x3e, 0x15, 0xd8, 0xd4, 0x6b, 0x52, 0xa0,
+	0x4b, 0x31, 0x1e, 0x68, 0xb7, 0x5e, 0xd4, 0xf5, 0xb3, 0xdc, 0xca, 0x11, 0x08, 0xfa, 0x3e, 0x54,
+	0xc3, 0xbd, 0x4c, 0x74, 0x2d, 0x41, 0x56, 0xb4, 0x37, 0xda, 0xb8, 0x7e, 0x34, 0x12, 0xd7, 0x69,
+	0x9e, 0xea, 0xc4, 0x85, 0x33, 0xc9, 0xfb, 0x18, 0x8f, 0x4c, 0x82, 0xc4, 0x7d, 0x80, 0xfe, 0x54,
+	0xe3, 0xed, 0x68, 0xd9, 0x8a, 0x44, 0x49, 0xdc, 0x63, 0x1d, 0xcf, 0xc6, 0x8d, 0x63, 0xb0, 0xb8,
+	0x12, 0x1f, 0x50, 0x25, 0xde, 0xd7, 0xe7, 0xa4, 0x12, 0xbe, 0x35, 0xc4, 0xbe, 0xc3, 0xb5, 0x78,
+	0x71, 0x59, 0xbf, 0x10, 0x32, 0x4e, 0x08, 0x2a, 0x9d, 0xc5, 0x5a, 0x86, 0x89, 0xce, 0x0a, 0x75,
+	0x25, 0x13, 0x9d, 0x15, 0xee, 0x37, 0x26, 0x39, 0x8b, 0x37, 0x08, 0x13, 0x9c, 0x15, 0x40, 0x96,
+	0xfe, 0x3f, 0x07, 0xf9, 0x15, 0xf6, 0x3f, 0x23, 0x21, 0x07, 0x8a, 0x41, 0x13, 0x0d, 0xcd, 0x27,
+	0xd5, 0xe9, 0xe5, 0x55, 0xae, 0x71, 0x35, 0x15, 0xce, 0x15, 0x7a, 0x83, 0x2a, 0x74, 0x49, 0x3f,
+	0x4f, 0x24, 0xf3, 0xff, 0xdf, 0xa9, 0xc9, 0xaa, 0xb9, 0x4d, 0xb3, 0xd7, 0x23, 0x86, 0xf8, 0x4d,
+	0x28, 0xab, 0x2d, 0x2d, 0xf4, 0x46, 0x62, 0x6f, 0x40, 0xed, 0x8f, 0x35, 0xf4, 0xa3, 0x50, 0xb8,
+	0xe4, 0xeb, 0x54, 0xf2, 0xbc, 0x7e, 0x31, 0x41, 0xb2, 0x4b, 0x51, 0x43, 0xc2, 0x59, 0xef, 0x29,
+	0x59, 0x78, 0xa8, 0xc9, 0x95, 0x2c, 0x3c, 0xdc, 0xba, 0x3a, 0x52, 0xf8, 0x98, 0xa2, 0x12, 0xe1,
+	0x1e, 0x80, 0x6c, 0x0e, 0xa1, 0x44, 0x5b, 0x2a, 0x17, 0xd6, 0x68, 0x70, 0x88, 0xf7, 0x95, 0x74,
+	0x9d, 0x8a, 0xe5, 0xeb, 0x2e, 0x22, 0x76, 0x60, 0x79, 0x3e, 0xdb, 0x98, 0x95, 0x50, 0x6b, 0x07,
+	0x25, 0xce, 0x27, 0xdc, 0x29, 0x6a, 0x5c, 0x3b, 0x12, 0x87, 0x4b, 0xbf, 0x41, 0xa5, 0x5f, 0xd5,
+	0x1b, 0x09, 0xd2, 0x47, 0x0c, 0x97, 0x2c, 0xb6, 0xcf, 0xf3, 0x50, 0x7a, 0x6a, 0x5a, 0xb6, 0x8f,
+	0x6d, 0xd3, 0xee, 0x62, 0xb4, 0x0b, 0xd3, 0x34, 0x77, 0x47, 0x03, 0xb1, 0xda, 0xc9, 0x88, 0x06,
+	0xe2, 0x50, 0x29, 0x5f, 0x5f, 0xa0, 0x82, 0x1b, 0xfa, 0x39, 0x22, 0x78, 0x28, 0x59, 0x37, 0x59,
+	0x13, 0x40, 0xbb, 0x85, 0x5e, 0xc2, 0x0c, 0x6f, 0xe1, 0x47, 0x18, 0x85, 0x8a, 0x6a, 0x8d, 0xcb,
+	0xc9, 0xc0, 0xa4, 0xb5, 0xac, 0x8a, 0xf1, 0x28, 0x1e, 0x91, 0x33, 0x01, 0x90, 0x1d, 0xa9, 0xa8,
+	0x47, 0x63, 0x9d, 0xac, 0xc6, 0x42, 0x3a, 0x42, 0x92, 0x4d, 0x55, 0x99, 0xbd, 0x00, 0x97, 0xc8,
+	0xfd, 0x0e, 0xe4, 0x1e, 0x9b, 0xde, 0x1e, 0x8a, 0xe4, 0x5e, 0xe5, 0xc5, 0x6d, 0xa3, 0x91, 0x04,
+	0xe2, 0x52, 0xae, 0x52, 0x29, 0x17, 0x59, 0x28, 0x53, 0xa5, 0xd0, 0x37, 0xa5, 0xcc, 0x7e, 0xec,
+	0xb9, 0x6d, 0xd4, 0x7e, 0xa1, 0xb7, 0xbb, 0x51, 0xfb, 0x85, 0x5f, 0xe8, 0xa6, 0xdb, 0x8f, 0x48,
+	0xd9, 0x9f, 0x10, 0x39, 0x23, 0x28, 0x88, 0x87, 0xa9, 0x28, 0xf2, 0x9c, 0x27, 0xf2, 0x9a, 0xb5,
+	0x31, 0x9f, 0x06, 0xe6, 0xd2, 0xae, 0x51, 0x69, 0x57, 0xf4, 0x7a, 0xcc, 0x5b, 0x1c, 0xf3, 0x81,
+	0x76, 0xeb, 0x8e, 0x86, 0xbe, 0x0f, 0x20, 0x9b, 0x76, 0xb1, 0x3d, 0x18, 0x6d, 0x04, 0xc6, 0xf6,
+	0x60, 0xac, 0xdf, 0xa7, 0x2f, 0x52, 0xb9, 0x37, 0xf5, 0x6b, 0x51, 0xb9, 0xbe, 0x6b, 0xda, 0xde,
+	0x4b, 0xec, 0xde, 0x66, 0x75, 0x7f, 0x6f, 0xcf, 0x1a, 0x91, 0x29, 0xbb, 0x50, 0x0c, 0x6a, 0xcd,
+	0xd1, 0x78, 0x1b, 0xed, 0xfe, 0x44, 0xe3, 0x6d, 0xac, 0x19, 0x13, 0x0e, 0x3c, 0xa1, 0xf5, 0x22,
+	0x50, 0xc9, 0x16, 0xfc, 0xcb, 0x1a, 0xe4, 0xc8, 0x91, 0x9c, 0x1c, 0x4f, 0x64, 0xb9, 0x27, 0x3a,
+	0xfb, 0x58, 0xc5, 0x3a, 0x3a, 0xfb, 0x78, 0xa5, 0x28, 0x7c, 0x3c, 0x21, 0xd7, 0xb5, 0x26, 0xab,
+	0xa3, 0x90, 0x99, 0x3a, 0x50, 0x52, 0xca, 0x40, 0x28, 0x81, 0x59, 0xb8, 0x02, 0x1e, 0x4d, 0x78,
+	0x09, 0x35, 0x24, 0xfd, 0x12, 0x95, 0x77, 0x8e, 0x25, 0x3c, 0x2a, 0xaf, 0xc7, 0x30, 0x88, 0x40,
+	0x3e, 0x3b, 0xbe, 0xf3, 0x13, 0x66, 0x17, 0xde, 0xfd, 0x0b, 0xe9, 0x08, 0xa9, 0xb3, 0x93, 0x5b,
+	0xff, 0x15, 0x94, 0xd5, 0xd2, 0x0f, 0x4a, 0x50, 0x3e, 0x52, 0xa3, 0x8f, 0x66, 0x92, 0xa4, 0xca,
+	0x51, 0x38, 0xb6, 0x51, 0x91, 0xa6, 0x82, 0x46, 0x04, 0x0f, 0x20, 0xcf, 0x4b, 0x40, 0x49, 0x26,
+	0x0d, 0x97, 0xf1, 0x93, 0x4c, 0x1a, 0xa9, 0x1f, 0x85, 0xcf, 0xcf, 0x54, 0x22, 0xb9, 0x8a, 0x8a,
+	0x6c, 0xcd, 0xa5, 0x3d, 0xc2, 0x7e, 0x9a, 0x34, 0x59, 0xb6, 0x4d, 0x93, 0xa6, 0x54, 0x08, 0xd2,
+	0xa4, 0xf5, 0xb1, 0xcf, 0xe3, 0x81, 0xb8, 0x5e, 0xa3, 0x14, 0x66, 0x6a, 0x86, 0xd4, 0x8f, 0x42,
+	0x49, 0xba, 0xde, 0x48, 0x81, 0x22, 0x3d, 0x1e, 0x00, 0xc8, 0x72, 0x54, 0xf4, 0xcc, 0x9a, 0xd8,
+	0x29, 0x88, 0x9e, 0x59, 0x93, 0x2b, 0x5a, 0xe1, 0x18, 0x2b, 0xe5, 0xb2, 0xdb, 0x15, 0x91, 0xfc,
+	0x85, 0x06, 0x28, 0x5e, 0xb0, 0x42, 0xef, 0x24, 0x73, 0x4f, 0xec, 0x3a, 0x34, 0xde, 0x7d, 0x3d,
+	0xe4, 0xa4, 0x80, 0x2c, 0x55, 0xea, 0x52, 0xec, 0xd1, 0x2b, 0xa2, 0xd4, 0xe7, 0x1a, 0x54, 0x42,
+	0x45, 0x2e, 0xf4, 0x66, 0x8a, 0x4f, 0x23, 0xad, 0x87, 0xc6, 0x5b, 0xc7, 0xe2, 0x25, 0x1d, 0xe6,
+	0x95, 0x15, 0x20, 0x6e, 0x35, 0xbf, 0xa3, 0x41, 0x35, 0x5c, 0x0b, 0x43, 0x29, 0xbc, 0x63, 0x1d,
+	0x8b, 0xc6, 0xcd, 0xe3, 0x11, 0x8f, 0x76, 0x8f, 0xbc, 0xd0, 0x0c, 0x20, 0xcf, 0x8b, 0x66, 0x49,
+	0x0b, 0x3f, 0xdc, 0xe2, 0x48, 0x5a, 0xf8, 0x91, 0x8a, 0x5b, 0xc2, 0xc2, 0x77, 0x9d, 0x01, 0x56,
+	0xb6, 0x19, 0xaf, 0xa5, 0xa5, 0x49, 0x3b, 0x7a, 0x9b, 0x45, 0x0a, 0x71, 0x69, 0xd2, 0xe4, 0x36,
+	0x13, 0x25, 0x33, 0x94, 0xc2, 0xec, 0x98, 0x6d, 0x16, 0xad, 0xb8, 0x25, 0x6c, 0x33, 0x2a, 0x50,
+	0xd9, 0x66, 0xb2, 0x94, 0x95, 0xb4, 0xcd, 0x62, 0xdd, 0x98, 0xa4, 0x6d, 0x16, 0xaf, 0x86, 0x25,
+	0xf8, 0x91, 0xca, 0x0d, 0x6d, 0xb3, 0xb3, 0x09, 0xc5, 0x2e, 0xf4, 0x6e, 0x8a, 0x11, 0x13, 0x7b,
+	0x3b, 0x8d, 0xdb, 0xaf, 0x89, 0x9d, 0xba, 0xc6, 0x99, 0xf9, 0xc5, 0x1a, 0xff, 0x23, 0x0d, 0xe6,
+	0x92, 0xea, 0x63, 0x28, 0x45, 0x4e, 0x4a, 0x2b, 0xa8, 0xb1, 0xf8, 0xba, 0xe8, 0x47, 0x5b, 0x2b,
+	0x58, 0xf5, 0x0f, 0xfb, 0x5f, 0xb4, 0x9a, 0x2f, 0xae, 0xc2, 0x15, 0x98, 0x69, 0x8d, 0xac, 0x27,
+	0xf8, 0x10, 0x9d, 0x2d, 0x64, 0x1a, 0x15, 0xc2, 0xd7, 0x71, 0xad, 0xcf, 0xe8, 0x5f, 0xbd, 0x58,
+	0xc8, 0xec, 0x96, 0x01, 0x02, 0x84, 0xa9, 0x7f, 0xff, 0x72, 0x5e, 0xfb, 0xaf, 0x2f, 0xe7, 0xb5,
+	0xff, 0xf9, 0x72, 0x5e, 0xfb, 0xe9, 0xff, 0xcd, 0x4f, 0xbd, 0xb8, 0xd6, 0x77, 0xa8, 0x5a, 0x8b,
+	0x96, 0xd3, 0x94, 0x7f, 0x89, 0x63, 0xb9, 0xa9, 0xaa, 0xba, 0x3b, 0x43, 0xff, 0x74, 0xc6, 0xf2,
+	0xcf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x82, 0x9b, 0xab, 0xde, 0x11, 0x44, 0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -11648,6 +11719,18 @@ func (m *StatusResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		i -= len(m.XXX_unrecognized)
 		copy(dAtA[i:], m.XXX_unrecognized)
 	}
+	if m.DowngradeInfo != nil {
+		{
+			size, err := m.DowngradeInfo.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintRpc(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0x6a
+	}
 	if m.DbSizeQuota != 0 {
 		i = encodeVarintRpc(dAtA, i, uint64(m.DbSizeQuota))
 		i--
@@ -11731,6 +11814,50 @@ func (m *StatusResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	return len(dAtA) - i, nil
 }
 
+func (m *DowngradeInfo) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *DowngradeInfo) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DowngradeInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.XXX_unrecognized != nil {
+		i -= len(m.XXX_unrecognized)
+		copy(dAtA[i:], m.XXX_unrecognized)
+	}
+	if len(m.TargetVersion) > 0 {
+		i -= len(m.TargetVersion)
+		copy(dAtA[i:], m.TargetVersion)
+		i = encodeVarintRpc(dAtA, i, uint64(len(m.TargetVersion)))
+		i--
+		dAtA[i] = 0x12
+	}
+	if m.Enabled {
+		i--
+		if m.Enabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x8
+	}
+	return len(dAtA) - i, nil
+}
+
 func (m *AuthEnableRequest) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -14598,6 +14725,29 @@ func (m *StatusResponse) Size() (n int) {
 	if m.DbSizeQuota != 0 {
 		n += 1 + sovRpc(uint64(m.DbSizeQuota))
 	}
+	if m.DowngradeInfo != nil {
+		l = m.DowngradeInfo.Size()
+		n += 1 + l + sovRpc(uint64(l))
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func (m *DowngradeInfo) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.Enabled {
+		n += 2
+	}
+	l = len(m.TargetVersion)
+	if l > 0 {
+		n += 1 + l + sovRpc(uint64(l))
+	}
 	if m.XXX_unrecognized != nil {
 		n += len(m.XXX_unrecognized)
 	}
@@ -22853,6 +23003,145 @@ func (m *StatusResponse) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
+		case 13:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DowngradeInfo", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpc
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpc
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRpc
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.DowngradeInfo == nil {
+				m.DowngradeInfo = &DowngradeInfo{}
+			}
+			if err := m.DowngradeInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpc(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthRpc
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *DowngradeInfo) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpc
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: DowngradeInfo: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: DowngradeInfo: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpc
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Enabled = bool(v != 0)
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TargetVersion", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpc
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRpc
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthRpc
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.TargetVersion = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipRpc(dAtA[iNdEx:])
diff --git a/api/etcdserverpb/rpc.proto b/api/etcdserverpb/rpc.proto
index 604be785f..983dc0172 100644
--- a/api/etcdserverpb/rpc.proto
+++ b/api/etcdserverpb/rpc.proto
@@ -507,7 +507,9 @@ message RangeResponse {
   repeated mvccpb.KeyValue kvs = 2;
   // more indicates if there are more keys to return in the requested range.
   bool more = 3;
-  // count is set to the number of keys within the range when requested.
+  // count is set to the actual number of keys within the range when requested.
+  // Unlike Kvs, it is unaffected by limits and filters (e.g., Min/Max, Create/Modify, Revisions)
+  // and reflects the full count within the specified range.
   int64 count = 4;
 }
 
@@ -1194,10 +1196,19 @@ message StatusResponse {
   int64 dbSizeInUse = 9 [(versionpb.etcd_version_field)="3.4"];
   // isLearner indicates if the member is raft learner.
   bool isLearner = 10 [(versionpb.etcd_version_field)="3.4"];
-  // storageVersion is the version of the db file. It might be get updated with delay in relationship to the target cluster version.
+  // storageVersion is the version of the db file. It might be updated with delay in relationship to the target cluster version.
   string storageVersion = 11 [(versionpb.etcd_version_field)="3.6"];
   // dbSizeQuota is the configured etcd storage quota in bytes (the value passed to etcd instance by flag --quota-backend-bytes)
   int64 dbSizeQuota = 12 [(versionpb.etcd_version_field)="3.6"];
+  // downgradeInfo indicates if there is downgrade process.
+  DowngradeInfo downgradeInfo = 13 [(versionpb.etcd_version_field)="3.6"];
+}
+
+message DowngradeInfo {
+	// enabled indicates whether the cluster is enabled to downgrade.
+  bool enabled = 1;
+	// targetVersion is the target downgrade version.
+  string targetVersion = 2;
 }
 
 message AuthEnableRequest {
diff --git a/api/go.mod b/api/go.mod
index bc5e202bc..51967d0df 100644
--- a/api/go.mod
+++ b/api/go.mod
@@ -1,16 +1,16 @@
 module go.etcd.io/etcd/api/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 require (
 	github.com/coreos/go-semver v0.3.1
 	github.com/gogo/protobuf v1.3.2
 	github.com/golang/protobuf v1.5.4
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3
 	github.com/stretchr/testify v1.10.0
-	google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489
+	google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb
 	google.golang.org/grpc v1.70.0
 	google.golang.org/protobuf v1.36.5
 )
@@ -18,13 +18,13 @@ require (
 require (
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/rogpeppe/go-internal v1.13.1 // indirect
+	github.com/rogpeppe/go-internal v1.14.1 // indirect
 	go.opentelemetry.io/otel v1.34.0 // indirect
 	go.opentelemetry.io/otel/sdk v1.34.0 // indirect
-	golang.org/x/net v0.34.0 // indirect
+	golang.org/x/net v0.36.0 // indirect
 	golang.org/x/sys v0.30.0 // indirect
 	golang.org/x/text v0.22.0 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
 
diff --git a/api/go.sum b/api/go.sum
index 2b7a2fd60..5bc304426 100644
--- a/api/go.sum
+++ b/api/go.sum
@@ -10,12 +10,12 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
 github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -24,8 +24,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -51,8 +51,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
+golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -73,10 +73,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
 google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
 google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
 google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
diff --git a/client/internal/v2/go.mod b/client/internal/v2/go.mod
index 1c3a0b2c3..7b7e0a473 100644
--- a/client/internal/v2/go.mod
+++ b/client/internal/v2/go.mod
@@ -1,8 +1,8 @@
 module go.etcd.io/etcd/client/v2
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 require (
 	github.com/stretchr/testify v1.10.0
diff --git a/client/internal/v2/go.sum b/client/internal/v2/go.sum
index f3a0fb387..51cbd9176 100644
--- a/client/internal/v2/go.sum
+++ b/client/internal/v2/go.sum
@@ -9,8 +9,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/client/pkg/go.mod b/client/pkg/go.mod
index 0976583d1..cfef8ade3 100644
--- a/client/pkg/go.mod
+++ b/client/pkg/go.mod
@@ -1,8 +1,8 @@
 module go.etcd.io/etcd/client/pkg/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 require (
 	github.com/coreos/go-systemd/v22 v22.5.0
@@ -15,7 +15,7 @@ require (
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/kr/pretty v0.3.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/rogpeppe/go-internal v1.13.1 // indirect
+	github.com/rogpeppe/go-internal v1.14.1 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/client/pkg/go.sum b/client/pkg/go.sum
index 9afaa25cf..5de2e9fdb 100644
--- a/client/pkg/go.sum
+++ b/client/pkg/go.sum
@@ -15,8 +15,8 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
diff --git a/client/v3/go.mod b/client/v3/go.mod
index 2604a72c6..98b2640ba 100644
--- a/client/v3/go.mod
+++ b/client/v3/go.mod
@@ -1,14 +1,14 @@
 module go.etcd.io/etcd/client/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 require (
 	github.com/coreos/go-semver v0.3.1
 	github.com/dustin/go-humanize v1.0.1
 	github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1
-	github.com/prometheus/client_golang v1.20.5
+	github.com/prometheus/client_golang v1.21.0
 	github.com/stretchr/testify v1.10.0
 	go.etcd.io/etcd/api/v3 v3.6.0-alpha.0
 	go.etcd.io/etcd/client/pkg/v3 v3.6.0-alpha.0
@@ -25,8 +25,8 @@ require (
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
-	github.com/klauspost/compress v1.17.9 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
+	github.com/klauspost/compress v1.18.0 // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/prometheus/client_model v0.6.1 // indirect
@@ -35,11 +35,11 @@ require (
 	go.opentelemetry.io/otel/metric v1.34.0 // indirect
 	go.opentelemetry.io/otel/trace v1.34.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
-	golang.org/x/net v0.34.0 // indirect
+	golang.org/x/net v0.36.0 // indirect
 	golang.org/x/sys v0.30.0 // indirect
 	golang.org/x/text v0.22.0 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
 	google.golang.org/protobuf v1.36.5 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/client/v3/go.sum b/client/v3/go.sum
index e8a7ed1f9..84124bc68 100644
--- a/client/v3/go.sum
+++ b/client/v3/go.sum
@@ -20,20 +20,20 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
 github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
 github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA=
 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -44,16 +44,16 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
-github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
+github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
 github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
 github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
 github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
 github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
 github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -85,8 +85,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
+golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -107,10 +107,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
 google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
 google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
 google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
diff --git a/client/v3/kv.go b/client/v3/kv.go
index 8d0c595d1..6b94b8196 100644
--- a/client/v3/kv.go
+++ b/client/v3/kv.go
@@ -134,7 +134,7 @@ func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*C
 	if err != nil {
 		return nil, ContextError(ctx, err)
 	}
-	return (*CompactResponse)(resp), err
+	return (*CompactResponse)(resp), nil
 }
 
 func (kv *kv) Txn(ctx context.Context) Txn {
diff --git a/client/v3/retry_interceptor.go b/client/v3/retry_interceptor.go
index 2b9301a58..7703e673b 100644
--- a/client/v3/retry_interceptor.go
+++ b/client/v3/retry_interceptor.go
@@ -351,11 +351,11 @@ func isContextError(err error) bool {
 func contextErrToGRPCErr(err error) error {
 	switch {
 	case errors.Is(err, context.DeadlineExceeded):
-		return status.Errorf(codes.DeadlineExceeded, err.Error())
+		return status.Error(codes.DeadlineExceeded, err.Error())
 	case errors.Is(err, context.Canceled):
-		return status.Errorf(codes.Canceled, err.Error())
+		return status.Error(codes.Canceled, err.Error())
 	default:
-		return status.Errorf(codes.Unknown, err.Error())
+		return status.Error(codes.Unknown, err.Error())
 	}
 }
 
diff --git a/etcdctl/ctlv3/command/printer.go b/etcdctl/ctlv3/command/printer.go
index 90a76ebfc..12460259e 100644
--- a/etcdctl/ctlv3/command/printer.go
+++ b/etcdctl/ctlv3/command/printer.go
@@ -17,6 +17,7 @@ package command
 import (
 	"errors"
 	"fmt"
+	"strconv"
 	"strings"
 
 	"github.com/dustin/go-humanize"
@@ -220,7 +221,7 @@ func makeEndpointHealthTable(healthList []epHealth) (hdr []string, rows [][]stri
 func makeEndpointStatusTable(statusList []epStatus) (hdr []string, rows [][]string) {
 	hdr = []string{
 		"endpoint", "ID", "version", "storage version", "db size", "in use", "percentage not in use", "quota", "is leader", "is learner", "raft term",
-		"raft index", "raft applied index", "errors",
+		"raft index", "raft applied index", "errors", "downgrade target version", "downgrade enabled",
 	}
 	for _, status := range statusList {
 		rows = append(rows, []string{
@@ -238,6 +239,8 @@ func makeEndpointStatusTable(statusList []epStatus) (hdr []string, rows [][]stri
 			fmt.Sprint(status.Resp.RaftIndex),
 			fmt.Sprint(status.Resp.RaftAppliedIndex),
 			fmt.Sprint(strings.Join(status.Resp.Errors, ", ")),
+			status.Resp.DowngradeInfo.GetTargetVersion(),
+			strconv.FormatBool(status.Resp.DowngradeInfo.GetEnabled()),
 		})
 	}
 	return hdr, rows
diff --git a/etcdctl/ctlv3/command/printer_fields.go b/etcdctl/ctlv3/command/printer_fields.go
index 86f1c70d7..1ca4c876e 100644
--- a/etcdctl/ctlv3/command/printer_fields.go
+++ b/etcdctl/ctlv3/command/printer_fields.go
@@ -203,6 +203,8 @@ func (p *fieldsPrinter) EndpointStatus(eps []epStatus) {
 		fmt.Println(`"RaftAppliedIndex" :`, ep.Resp.RaftAppliedIndex)
 		fmt.Println(`"Errors" :`, ep.Resp.Errors)
 		fmt.Printf("\"Endpoint\" : %q\n", ep.Ep)
+		fmt.Printf("\"DowngradeTargetVersion\" : %q\n", ep.Resp.DowngradeInfo.GetTargetVersion())
+		fmt.Println(`"DowngradeEnabled" :`, ep.Resp.DowngradeInfo.GetEnabled())
 		fmt.Println()
 	}
 }
diff --git a/etcdctl/ctlv3/ctl.go b/etcdctl/ctlv3/ctl.go
index 6686940ce..992538503 100644
--- a/etcdctl/ctlv3/ctl.go
+++ b/etcdctl/ctlv3/ctl.go
@@ -23,6 +23,7 @@ import (
 
 	"go.etcd.io/etcd/api/v3/version"
 	"go.etcd.io/etcd/etcdctl/v3/ctlv3/command"
+	"go.etcd.io/etcd/etcdctl/v3/util"
 	"go.etcd.io/etcd/pkg/v3/cobrautl"
 )
 
@@ -102,7 +103,7 @@ func init() {
 }
 
 func usageFunc(c *cobra.Command) error {
-	return cobrautl.UsageFunc(c, version.Version, version.APIVersion)
+	return util.UsageFunc(c, version.Version, version.APIVersion)
 }
 
 func Start() error {
diff --git a/etcdctl/go.mod b/etcdctl/go.mod
index 9856ea54f..4dca248df 100644
--- a/etcdctl/go.mod
+++ b/etcdctl/go.mod
@@ -1,15 +1,15 @@
 module go.etcd.io/etcd/etcdctl/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 require (
 	github.com/bgentry/speakeasy v0.2.0
-	github.com/cheggaaa/pb/v3 v3.1.6
+	github.com/cheggaaa/pb/v3 v3.1.7
 	github.com/dustin/go-humanize v1.0.1
 	github.com/olekukonko/tablewriter v0.0.5
-	github.com/spf13/cobra v1.8.1
+	github.com/spf13/cobra v1.9.1
 	github.com/spf13/pflag v1.0.6
 	github.com/stretchr/testify v1.10.0
 	go.etcd.io/etcd/api/v3 v3.6.0-alpha.0
@@ -29,7 +29,7 @@ require (
 	github.com/fatih/color v1.18.0 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/protobuf v1.5.4 // indirect
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/mattn/go-colorable v0.1.14 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
@@ -38,11 +38,11 @@ require (
 	github.com/rivo/uniseg v0.4.7 // indirect
 	go.opentelemetry.io/auto/sdk v1.1.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
-	golang.org/x/net v0.34.0 // indirect
+	golang.org/x/net v0.36.0 // indirect
 	golang.org/x/sys v0.30.0 // indirect
 	golang.org/x/text v0.22.0 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
 	google.golang.org/protobuf v1.36.5 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/etcdctl/go.sum b/etcdctl/go.sum
index 685da65f1..2966b4e18 100644
--- a/etcdctl/go.sum
+++ b/etcdctl/go.sum
@@ -6,13 +6,13 @@ github.com/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE5
 github.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cheggaaa/pb/v3 v3.1.6 h1:h0x+vd7EiUohAJ29DJtJy+SNAc55t/elW3jCD086EXk=
-github.com/cheggaaa/pb/v3 v3.1.6/go.mod h1:urxmfVtaxT+9aWk92DbsvXFZtNSWQSO5TRAp+MJ3l1s=
+github.com/cheggaaa/pb/v3 v3.1.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI=
+github.com/cheggaaa/pb/v3 v3.1.7/go.mod h1:/Ji89zfVPeC/u5j8ukD0MBPHt2bzTYp74lQ7KlgFWTQ=
 github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
 github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
 github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
@@ -28,22 +28,22 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
 github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA=
 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -61,8 +61,8 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
-github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
+github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
 github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
 github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
@@ -72,12 +72,11 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
 github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
@@ -111,8 +110,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
+golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -136,10 +135,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
 google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
 google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
 google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
diff --git a/etcdctl/util/help.go b/etcdctl/util/help.go
new file mode 100644
index 000000000..0e8035313
--- /dev/null
+++ b/etcdctl/util/help.go
@@ -0,0 +1,180 @@
+// Copyright 2025 The etcd Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// copied from https://github.com/rkt/rkt/blob/master/rkt/help.go
+
+package util
+
+import (
+	"fmt"
+	"io"
+	"os"
+	"strings"
+	"text/tabwriter"
+	"text/template"
+
+	"github.com/spf13/cobra"
+	"github.com/spf13/pflag"
+)
+
+var (
+	commandUsageTemplate *template.Template
+	templFuncs           = template.FuncMap{
+		"descToLines": func(s string) []string {
+			// trim leading/trailing whitespace and split into slice of lines
+			return strings.Split(strings.Trim(s, "\n\t "), "\n")
+		},
+		"cmdName": func(cmd *cobra.Command, startCmd *cobra.Command) string {
+			parts := []string{cmd.Name()}
+			for cmd.HasParent() && cmd.Parent().Name() != startCmd.Name() {
+				cmd = cmd.Parent()
+				parts = append([]string{cmd.Name()}, parts...)
+			}
+			return strings.Join(parts, " ")
+		},
+		"indent": func(s string) string {
+			pad := strings.Repeat(" ", 2)
+			return pad + strings.Replace(s, "\n", "\n"+pad, -1)
+		},
+	}
+)
+
+func init() {
+	commandUsage := `
+{{ $cmd := .Cmd }}\
+{{ $cmdname := cmdName .Cmd .Cmd.Root }}\
+NAME:
+{{if not .Cmd.HasParent}}\
+{{printf "%s - %s" .Cmd.Name .Cmd.Short | indent}}
+{{else}}\
+{{printf "%s - %s" $cmdname .Cmd.Short | indent}}
+{{end}}\
+
+USAGE:
+{{printf "%s" .Cmd.UseLine | indent}}
+{{ if not .Cmd.HasParent }}\
+
+VERSION:
+{{printf "%s" .Version | indent}}
+{{end}}\
+{{if .Cmd.HasSubCommands}}\
+
+API VERSION:
+{{.APIVersion | indent}}
+{{end}}\
+{{if .Cmd.HasExample}}\
+
+Examples:
+{{.Cmd.Example}}
+{{end}}\
+{{if .Cmd.HasSubCommands}}\
+
+COMMANDS:
+{{range .SubCommands}}\
+{{ $cmdname := cmdName . $cmd }}\
+{{ if .Runnable }}\
+{{printf "%s\t%s" $cmdname .Short | indent}}
+{{end}}\
+{{end}}\
+{{end}}\
+{{ if .Cmd.Long }}\
+
+DESCRIPTION:
+{{range $line := descToLines .Cmd.Long}}{{printf "%s" $line | indent}}
+{{end}}\
+{{end}}\
+{{if .Cmd.HasLocalFlags}}\
+
+OPTIONS:
+{{.LocalFlags}}\
+{{end}}\
+{{if .Cmd.HasInheritedFlags}}\
+
+GLOBAL OPTIONS:
+{{.GlobalFlags}}\
+{{end}}
+`[1:]
+
+	commandUsageTemplate = template.Must(template.New("command_usage").Funcs(templFuncs).Parse(strings.ReplaceAll(commandUsage, "\\\n", "")))
+}
+
+func etcdFlagUsages(flagSet *pflag.FlagSet) string {
+	x := new(strings.Builder)
+
+	flagSet.VisitAll(func(flag *pflag.Flag) {
+		if len(flag.Deprecated) > 0 {
+			return
+		}
+		var format string
+		if len(flag.Shorthand) > 0 {
+			format = "  -%s, --%s"
+		} else {
+			format = "   %s   --%s"
+		}
+		if len(flag.NoOptDefVal) > 0 {
+			format = format + "["
+		}
+		if flag.Value.Type() == "string" {
+			// put quotes on the value
+			format = format + "=%q"
+		} else {
+			format = format + "=%s"
+		}
+		if len(flag.NoOptDefVal) > 0 {
+			format = format + "]"
+		}
+		format = format + "\t%s\n"
+		shorthand := flag.Shorthand
+		fmt.Fprintf(x, format, shorthand, flag.Name, flag.DefValue, flag.Usage)
+	})
+
+	return x.String()
+}
+
+func getSubCommands(cmd *cobra.Command) []*cobra.Command {
+	var subCommands []*cobra.Command
+	for _, subCmd := range cmd.Commands() {
+		subCommands = append(subCommands, subCmd)
+		subCommands = append(subCommands, getSubCommands(subCmd)...)
+	}
+	return subCommands
+}
+
+func UsageFunc(cmd *cobra.Command, version, APIVersion string) error {
+	subCommands := getSubCommands(cmd)
+	tabOut := getTabOutWithWriter(os.Stdout)
+	commandUsageTemplate.Execute(tabOut, struct {
+		Cmd         *cobra.Command
+		LocalFlags  string
+		GlobalFlags string
+		SubCommands []*cobra.Command
+		Version     string
+		APIVersion  string
+	}{
+		cmd,
+		etcdFlagUsages(cmd.LocalFlags()),
+		etcdFlagUsages(cmd.InheritedFlags()),
+		subCommands,
+		version,
+		APIVersion,
+	})
+	tabOut.Flush()
+	return nil
+}
+
+func getTabOutWithWriter(writer io.Writer) *tabwriter.Writer {
+	aTabOut := new(tabwriter.Writer)
+	aTabOut.Init(writer, 0, 8, 1, '\t', 0)
+	return aTabOut
+}
diff --git a/etcdutl/go.mod b/etcdutl/go.mod
index 25fa3fc79..2c4fb823a 100644
--- a/etcdutl/go.mod
+++ b/etcdutl/go.mod
@@ -1,8 +1,8 @@
 module go.etcd.io/etcd/etcdutl/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 replace (
 	go.etcd.io/etcd/api/v3 => ../api
@@ -25,7 +25,7 @@ require (
 	github.com/coreos/go-semver v0.3.1
 	github.com/dustin/go-humanize v1.0.1
 	github.com/olekukonko/tablewriter v0.0.5
-	github.com/spf13/cobra v1.8.1
+	github.com/spf13/cobra v1.9.1
 	github.com/stretchr/testify v1.10.0
 	go.etcd.io/bbolt v1.4.0
 	go.etcd.io/etcd/api/v3 v3.6.0-alpha.0
@@ -49,19 +49,19 @@ require (
 	github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/google/btree v1.1.3 // indirect
-	github.com/google/go-cmp v0.6.0 // indirect
+	github.com/google/go-cmp v0.7.0 // indirect
 	github.com/google/uuid v1.6.0 // indirect
 	github.com/gorilla/websocket v1.4.2 // indirect
 	github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect
 	github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/jonboulle/clockwork v0.5.0 // indirect
-	github.com/klauspost/compress v1.17.9 // indirect
+	github.com/klauspost/compress v1.18.0 // indirect
 	github.com/mattn/go-runewidth v0.0.16 // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/prometheus/client_golang v1.20.5 // indirect
+	github.com/prometheus/client_golang v1.21.0 // indirect
 	github.com/prometheus/client_model v0.6.1 // indirect
 	github.com/prometheus/common v0.62.0 // indirect
 	github.com/prometheus/procfs v0.15.1 // indirect
@@ -82,13 +82,13 @@ require (
 	go.opentelemetry.io/otel/trace v1.34.0 // indirect
 	go.opentelemetry.io/proto/otlp v1.5.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
-	golang.org/x/crypto v0.33.0 // indirect
-	golang.org/x/net v0.34.0 // indirect
+	golang.org/x/crypto v0.35.0 // indirect
+	golang.org/x/net v0.36.0 // indirect
 	golang.org/x/sys v0.30.0 // indirect
 	golang.org/x/text v0.22.0 // indirect
 	golang.org/x/time v0.10.0 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
 	google.golang.org/grpc v1.70.0 // indirect
 	google.golang.org/protobuf v1.36.5 // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
diff --git a/etcdutl/go.sum b/etcdutl/go.sum
index ea6995ba7..95d3a0f29 100644
--- a/etcdutl/go.sum
+++ b/etcdutl/go.sum
@@ -10,7 +10,7 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr
 github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
 github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -31,8 +31,8 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
 github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
 github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
@@ -41,16 +41,16 @@ github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpS
 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
 github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -66,8 +66,8 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
-github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
+github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
 github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
 github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
@@ -77,16 +77,15 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
 github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
 github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
 github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -132,8 +131,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
-golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
+golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
+golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -141,8 +140,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
+golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -168,10 +167,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
 google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
 google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
 google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
diff --git a/go.mod b/go.mod
index ca4f2a077..357fc0cf2 100644
--- a/go.mod
+++ b/go.mod
@@ -1,8 +1,8 @@
 module go.etcd.io/etcd/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 replace (
 	go.etcd.io/etcd/api/v3 => ./api
@@ -18,10 +18,10 @@ replace (
 
 require (
 	github.com/bgentry/speakeasy v0.2.0
-	github.com/cheggaaa/pb/v3 v3.1.6
+	github.com/cheggaaa/pb/v3 v3.1.7
 	github.com/coreos/go-semver v0.3.1
 	github.com/dustin/go-humanize v1.0.1
-	github.com/spf13/cobra v1.8.1
+	github.com/spf13/cobra v1.9.1
 	github.com/stretchr/testify v1.10.0
 	go.etcd.io/bbolt v1.4.0
 	go.etcd.io/etcd/api/v3 v3.6.0-alpha.0
@@ -55,23 +55,23 @@ require (
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/google/btree v1.1.3 // indirect
-	github.com/google/go-cmp v0.6.0 // indirect
+	github.com/google/go-cmp v0.7.0 // indirect
 	github.com/google/uuid v1.6.0 // indirect
 	github.com/gorilla/websocket v1.4.2 // indirect
 	github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
 	github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect
 	github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/jonboulle/clockwork v0.5.0 // indirect
-	github.com/klauspost/compress v1.17.9 // indirect
+	github.com/klauspost/compress v1.18.0 // indirect
 	github.com/mattn/go-colorable v0.1.14 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mattn/go-runewidth v0.0.16 // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 	github.com/olekukonko/tablewriter v0.0.5 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/prometheus/client_golang v1.20.5 // indirect
+	github.com/prometheus/client_golang v1.21.0 // indirect
 	github.com/prometheus/client_model v0.6.1 // indirect
 	github.com/prometheus/common v0.62.0 // indirect
 	github.com/prometheus/procfs v0.15.1 // indirect
@@ -92,12 +92,12 @@ require (
 	go.opentelemetry.io/otel/trace v1.34.0 // indirect
 	go.opentelemetry.io/proto/otlp v1.5.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
-	golang.org/x/crypto v0.33.0 // indirect
-	golang.org/x/net v0.34.0 // indirect
+	golang.org/x/crypto v0.35.0 // indirect
+	golang.org/x/net v0.36.0 // indirect
 	golang.org/x/sys v0.30.0 // indirect
 	golang.org/x/text v0.22.0 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
diff --git a/go.sum b/go.sum
index 3fb73e7c5..16e860331 100644
--- a/go.sum
+++ b/go.sum
@@ -11,8 +11,8 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cheggaaa/pb/v3 v3.1.6 h1:h0x+vd7EiUohAJ29DJtJy+SNAc55t/elW3jCD086EXk=
-github.com/cheggaaa/pb/v3 v3.1.6/go.mod h1:urxmfVtaxT+9aWk92DbsvXFZtNSWQSO5TRAp+MJ3l1s=
+github.com/cheggaaa/pb/v3 v3.1.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI=
+github.com/cheggaaa/pb/v3 v3.1.7/go.mod h1:/Ji89zfVPeC/u5j8ukD0MBPHt2bzTYp74lQ7KlgFWTQ=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA=
@@ -21,7 +21,7 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr
 github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
 github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -59,8 +59,8 @@ github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
 github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
@@ -71,16 +71,16 @@ github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpS
 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
 github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -104,8 +104,8 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
-github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
+github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
 github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
@@ -116,17 +116,16 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
 github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
 github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
 github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -180,8 +179,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
-golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
+golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
+golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -197,8 +196,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
+golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -239,10 +238,10 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
 google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
diff --git a/pkg/cobrautl/help.go b/pkg/cobrautl/help.go
index 574578199..d4c4896b3 100644
--- a/pkg/cobrautl/help.go
+++ b/pkg/cobrautl/help.go
@@ -151,6 +151,8 @@ func getSubCommands(cmd *cobra.Command) []*cobra.Command {
 	return subCommands
 }
 
+// UsageFunc is the usage function for the cobra command.
+// Deprecated: Please use go.etcd.io/etcd/etcdctl/v3/util instead.
 func UsageFunc(cmd *cobra.Command, version, APIVersion string) error {
 	subCommands := getSubCommands(cmd)
 	tabOut := getTabOutWithWriter(os.Stdout)
diff --git a/pkg/featuregate/feature_gate.go b/pkg/featuregate/feature_gate.go
index c899616d9..343668fc3 100644
--- a/pkg/featuregate/feature_gate.go
+++ b/pkg/featuregate/feature_gate.go
@@ -112,8 +112,6 @@ type MutableFeatureGate interface {
 	Add(features map[Feature]FeatureSpec) error
 	// GetAll returns a copy of the map of known feature names to feature specs.
 	GetAll() map[Feature]FeatureSpec
-	// AddMetrics adds feature enablement metrics
-	AddMetrics()
 	// OverrideDefault sets a local override for the registered default value of a named
 	// feature. If the feature has not been previously registered (e.g. by a call to Add), has a
 	// locked default, or if the gate has already registered itself with a FlagSet, a non-nil
@@ -363,10 +361,6 @@ func (f *featureGate) AddFlag(fs *flag.FlagSet, flagName string) {
 		"Options are:\n"+strings.Join(known, "\n"))
 }
 
-func (f *featureGate) AddMetrics() {
-	// TODO(henrybear327): implement this.
-}
-
 // KnownFeatures returns a slice of strings describing the FeatureGate's known features.
 // Deprecated and GA features are hidden from the list.
 func (f *featureGate) KnownFeatures() []string {
diff --git a/pkg/go.mod b/pkg/go.mod
index 515c054ff..84104eb9e 100644
--- a/pkg/go.mod
+++ b/pkg/go.mod
@@ -1,13 +1,13 @@
 module go.etcd.io/etcd/pkg/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 require (
 	github.com/creack/pty v1.1.18
 	github.com/dustin/go-humanize v1.0.1
-	github.com/spf13/cobra v1.8.1
+	github.com/spf13/cobra v1.9.1
 	github.com/spf13/pflag v1.0.6
 	github.com/stretchr/testify v1.10.0
 	go.etcd.io/etcd/client/pkg/v3 v3.6.0-alpha.0
@@ -18,15 +18,16 @@ require (
 require (
 	github.com/coreos/go-systemd/v22 v22.5.0 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/google/go-cmp v0.7.0 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	go.opentelemetry.io/otel v1.34.0 // indirect
 	go.opentelemetry.io/otel/sdk v1.34.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
-	golang.org/x/net v0.34.0 // indirect
+	golang.org/x/net v0.36.0 // indirect
 	golang.org/x/sys v0.30.0 // indirect
 	golang.org/x/text v0.22.0 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
 	google.golang.org/protobuf v1.36.5 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/pkg/go.sum b/pkg/go.sum
index 63cee0e19..cee007e6d 100644
--- a/pkg/go.sum
+++ b/pkg/go.sum
@@ -1,6 +1,6 @@
 github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
 github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -14,8 +14,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
 github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@@ -26,12 +26,11 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
@@ -54,14 +53,14 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
 go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
 go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
 go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
+golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
 golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
 golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
 golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
 google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
 google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
 google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
diff --git a/scripts/etcd_version_annotations.txt b/scripts/etcd_version_annotations.txt
index 10c02b888..48071fb66 100644
--- a/scripts/etcd_version_annotations.txt
+++ b/scripts/etcd_version_annotations.txt
@@ -150,6 +150,9 @@ etcdserverpb.DeleteRangeResponse: "3.0"
 etcdserverpb.DeleteRangeResponse.deleted: ""
 etcdserverpb.DeleteRangeResponse.header: ""
 etcdserverpb.DeleteRangeResponse.prev_kvs: "3.1"
+etcdserverpb.DowngradeInfo: ""
+etcdserverpb.DowngradeInfo.enabled: ""
+etcdserverpb.DowngradeInfo.targetVersion: ""
 etcdserverpb.DowngradeRequest: "3.5"
 etcdserverpb.DowngradeRequest.CANCEL: ""
 etcdserverpb.DowngradeRequest.DowngradeAction: "3.5"
@@ -382,6 +385,7 @@ etcdserverpb.StatusResponse: "3.0"
 etcdserverpb.StatusResponse.dbSize: ""
 etcdserverpb.StatusResponse.dbSizeInUse: "3.4"
 etcdserverpb.StatusResponse.dbSizeQuota: "3.6"
+etcdserverpb.StatusResponse.downgradeInfo: "3.6"
 etcdserverpb.StatusResponse.errors: "3.4"
 etcdserverpb.StatusResponse.header: ""
 etcdserverpb.StatusResponse.isLearner: "3.4"
diff --git a/scripts/release_mod.sh b/scripts/release_mod.sh
index da6e63cc2..d2783f28e 100755
--- a/scripts/release_mod.sh
+++ b/scripts/release_mod.sh
@@ -31,7 +31,7 @@ function update_module_version() {
   local v2version="${2}"
   local modules
   run go mod tidy
-  modules=$(run go list -f '{{if not .Main}}{{if not .Indirect}}{{.Path}}{{end}}{{end}}' -m all)
+  modules=$(go mod edit -json | jq -r '.Require[] | select(.Indirect | not) | .Path')
 
   v3deps=$(echo "${modules}" | grep -E "${ROOT_MODULE}/.*/v3")
   for dep in ${v3deps}; do
@@ -97,16 +97,16 @@ function push_mod_tags_cmd {
 
   # Any module ccan be used for this
   local main_version
-  main_version=$(go list -f '{{.Version}}' -m "${ROOT_MODULE}/api/v3")
+  main_version=$(go mod edit -json | jq -r '.Require[] | select(.Path == "'"${ROOT_MODULE}"'/api/v3") | .Version')
   local tags=()
 
   keyid=$(get_gpg_key) || return 2
 
   for module in $(modules); do
     local version
-    version=$(go list -f '{{.Version}}' -m "${module}")
+    version=$(go mod edit -json | jq -r '.Require[] | select(.Path == "'"${module}"'") | .Version')
     local path
-    path=$(go list -f '{{.Path}}' -m "${module}")
+    path=$(go mod edit -json | jq -r '.Require[] | select(.Path == "'"${module}"'") | .Path')
     local subdir="${path//${ROOT_MODULE}\//}"
     local tag
     if [ -z "${version}" ]; then
@@ -121,7 +121,7 @@ function push_mod_tags_cmd {
     # consider main-module's tag as the latest.
     run sleep 2
     run git tag --local-user "${keyid}" --sign "${tag}" --message "${version}"
-    tags=("${tags[@]}" "${tag}")
+    tags+=("${tag}")
   done
   maybe_run git push -f "${REMOTE_REPO}" "${tags[@]}"
 }
diff --git a/scripts/test.sh b/scripts/test.sh
index b7932bbad..e7176dfce 100755
--- a/scripts/test.sh
+++ b/scripts/test.sh
@@ -508,7 +508,7 @@ function bom_pass {
 
 function dump_deps_of_module() {
   local module
-  if ! module=$(run go list -m); then
+  if ! module=$(run go mod edit -json | jq -r .Module.Path); then
     return 255
   fi
   run go mod edit -json | jq -r '.Require[] | .Path+","+.Version+","+if .Indirect then " (indirect)" else "" end+",'"${module}"'"'
diff --git a/server/auth/jwt.go b/server/auth/jwt.go
index e6aad1857..cab3f3eb9 100644
--- a/server/auth/jwt.go
+++ b/server/auth/jwt.go
@@ -121,7 +121,7 @@ func (t *tokenJWT) assign(ctx context.Context, username string, revision uint64)
 		zap.Uint64("revision", revision),
 		zap.String("token", token),
 	)
-	return token, err
+	return token, nil
 }
 
 func newTokenProviderJWT(lg *zap.Logger, optMap map[string]string) (*tokenJWT, error) {
diff --git a/server/etcdserver/api/v3election/v3electionpb/v3election.pb.go b/server/etcdserver/api/v3election/v3electionpb/v3election.pb.go
index 4a022f1b6..02369cde5 100644
--- a/server/etcdserver/api/v3election/v3electionpb/v3election.pb.go
+++ b/server/etcdserver/api/v3election/v3electionpb/v3election.pb.go
@@ -157,7 +157,7 @@ func (m *CampaignResponse) GetLeader() *LeaderKey {
 }
 
 type LeaderKey struct {
-	// name is the election identifier that correponds to the leadership key.
+	// name is the election identifier that corresponds to the leadership key.
 	Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
 	// key is an opaque key representing the ownership of the election. If the key
 	// is deleted, then leadership is lost.
diff --git a/server/etcdserver/api/v3election/v3electionpb/v3election.proto b/server/etcdserver/api/v3election/v3electionpb/v3election.proto
index 0bcaad875..6042776b9 100644
--- a/server/etcdserver/api/v3election/v3electionpb/v3election.proto
+++ b/server/etcdserver/api/v3election/v3electionpb/v3election.proto
@@ -76,7 +76,7 @@ message CampaignResponse {
 }
 
 message LeaderKey {
-  // name is the election identifier that correponds to the leadership key.
+  // name is the election identifier that corresponds to the leadership key.
   bytes name = 1;
   // key is an opaque key representing the ownership of the election. If the key
   // is deleted, then leadership is lost.
diff --git a/server/etcdserver/api/v3rpc/maintenance.go b/server/etcdserver/api/v3rpc/maintenance.go
index 92b41c317..e13095b83 100644
--- a/server/etcdserver/api/v3rpc/maintenance.go
+++ b/server/etcdserver/api/v3rpc/maintenance.go
@@ -262,10 +262,17 @@ func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (
 		DbSizeInUse:      ms.bg.Backend().SizeInUse(),
 		IsLearner:        ms.cs.IsLearner(),
 		DbSizeQuota:      ms.cg.Config().QuotaBackendBytes,
+		DowngradeInfo:    &pb.DowngradeInfo{Enabled: false},
 	}
 	if storageVersion := ms.vs.GetStorageVersion(); storageVersion != nil {
 		resp.StorageVersion = storageVersion.String()
 	}
+	if downgradeInfo := ms.vs.GetDowngradeInfo(); downgradeInfo != nil {
+		resp.DowngradeInfo = &pb.DowngradeInfo{
+			Enabled:       downgradeInfo.Enabled,
+			TargetVersion: downgradeInfo.TargetVersion,
+		}
+	}
 	if resp.Leader == raft.None {
 		resp.Errors = append(resp.Errors, errors.ErrNoLeader.Error())
 	}
diff --git a/server/etcdserver/metrics.go b/server/etcdserver/metrics.go
index 5f3c2f513..7176d30ad 100644
--- a/server/etcdserver/metrics.go
+++ b/server/etcdserver/metrics.go
@@ -140,6 +140,13 @@ var (
 		},
 		[]string{"server_id"},
 	)
+	serverFeatureEnabled = prometheus.NewGaugeVec(
+		prometheus.GaugeOpts{
+			Name: "etcd_server_feature_enabled",
+			Help: "Whether or not a feature is enabled. 1 is enabled, 0 is not.",
+		},
+		[]string{"name", "stage"},
+	)
 	fdUsed = prometheus.NewGauge(prometheus.GaugeOpts{
 		Namespace: "os",
 		Subsystem: "fd",
@@ -170,6 +177,7 @@ func init() {
 	prometheus.MustRegister(currentVersion)
 	prometheus.MustRegister(currentGoVersion)
 	prometheus.MustRegister(serverID)
+	prometheus.MustRegister(serverFeatureEnabled)
 	prometheus.MustRegister(learnerPromoteSucceed)
 	prometheus.MustRegister(learnerPromoteFailed)
 	prometheus.MustRegister(fdUsed)
diff --git a/server/etcdserver/server.go b/server/etcdserver/server.go
index 2c45553bc..008d23b55 100644
--- a/server/etcdserver/server.go
+++ b/server/etcdserver/server.go
@@ -342,6 +342,8 @@ func NewServer(cfg config.ServerConfig) (srv *EtcdServer, err error) {
 		firstCommitInTerm:     notify.NewNotifier(),
 		clusterVersionChanged: notify.NewNotifier(),
 	}
+
+	addFeatureGateMetrics(cfg.ServerFeatureGate, serverFeatureEnabled)
 	serverID.With(prometheus.Labels{"server_id": b.cluster.nodeID.String()}).Set(1)
 	srv.cluster.SetVersionChangedNotifier(srv.clusterVersionChanged)
 
@@ -2519,3 +2521,15 @@ func (s *EtcdServer) getTxPostLockInsideApplyHook() func() {
 func (s *EtcdServer) CorruptionChecker() CorruptionChecker {
 	return s.corruptionChecker
 }
+
+func addFeatureGateMetrics(fg featuregate.FeatureGate, guageVec *prometheus.GaugeVec) {
+	for feature, featureSpec := range fg.(featuregate.MutableFeatureGate).GetAll() {
+		var metricVal float64
+		if fg.Enabled(feature) {
+			metricVal = 1
+		} else {
+			metricVal = 0
+		}
+		guageVec.With(prometheus.Labels{"name": string(feature), "stage": string(featureSpec.PreRelease)}).Set(metricVal)
+	}
+}
diff --git a/server/go.mod b/server/go.mod
index cd0bcc29b..486f66eea 100644
--- a/server/go.mod
+++ b/server/go.mod
@@ -1,8 +1,8 @@
 module go.etcd.io/etcd/server/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 require (
 	github.com/coreos/go-semver v0.3.1
@@ -13,15 +13,15 @@ require (
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
 	github.com/golang/protobuf v1.5.4
 	github.com/google/btree v1.1.3
-	github.com/google/go-cmp v0.6.0
+	github.com/google/go-cmp v0.7.0
 	github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
 	github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3
 	github.com/jonboulle/clockwork v0.5.0
-	github.com/prometheus/client_golang v1.20.5
+	github.com/prometheus/client_golang v1.21.0
 	github.com/prometheus/client_model v0.6.1
 	github.com/soheilhy/cmux v0.1.5
-	github.com/spf13/cobra v1.8.1
+	github.com/spf13/cobra v1.9.1
 	github.com/stretchr/testify v1.10.0
 	github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802
 	github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2
@@ -37,10 +37,10 @@ require (
 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0
 	go.opentelemetry.io/otel/sdk v1.34.0
 	go.uber.org/zap v1.27.0
-	golang.org/x/crypto v0.33.0
-	golang.org/x/net v0.34.0
+	golang.org/x/crypto v0.35.0
+	golang.org/x/net v0.36.0
 	golang.org/x/time v0.10.0
-	google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489
+	google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb
 	google.golang.org/grpc v1.70.0
 	google.golang.org/protobuf v1.36.5
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1
@@ -58,7 +58,7 @@ require (
 	github.com/gorilla/websocket v1.4.2 // indirect
 	github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
-	github.com/klauspost/compress v1.17.9 // indirect
+	github.com/klauspost/compress v1.18.0 // indirect
 	github.com/kylelemons/godebug v1.1.0 // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
@@ -74,7 +74,7 @@ require (
 	go.uber.org/multierr v1.11.0 // indirect
 	golang.org/x/sys v0.30.0 // indirect
 	golang.org/x/text v0.22.0 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
 )
diff --git a/server/go.sum b/server/go.sum
index b70330f79..e99343d71 100644
--- a/server/go.sum
+++ b/server/go.sum
@@ -15,7 +15,7 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr
 github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
 github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -51,8 +51,8 @@ github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
 github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
@@ -63,16 +63,16 @@ github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpS
 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
 github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -87,8 +87,8 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
-github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
+github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
 github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
@@ -96,17 +96,16 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ
 github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
 github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
 github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
 github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
 github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -158,8 +157,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
-golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
+golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
+golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -175,8 +174,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
+golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -216,10 +215,10 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
 google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
diff --git a/tools/.golangci.yaml b/tools/.golangci.yaml
index 60925e0a4..0cc4524e9 100644
--- a/tools/.golangci.yaml
+++ b/tools/.golangci.yaml
@@ -30,12 +30,13 @@ linters:
     - revive
     - staticcheck
     - stylecheck
-    - tenv
     - testifylint
     - unconvert # Remove unnecessary type conversions
     - unparam
     - unused
     - usestdlibvars
+    # Disabled in the meanwhile, it raises several issues with new Go 1.24 functions
+    # - usetesting
     - whitespace
 linters-settings: # please keep this alphabetized
   goimports:
@@ -120,3 +121,5 @@ linters-settings: # please keep this alphabetized
       # to always require f-functions for stretchr/testify, but not for golang standard lib.
       # Also refer to https://github.com/etcd-io/etcd/pull/18741#issuecomment-2422395914
       require-f-funcs: true
+  usetesting:
+    os-mkdir-temp: false
diff --git a/tools/mod/go.mod b/tools/mod/go.mod
index 0856e51fb..1b790c2bd 100644
--- a/tools/mod/go.mod
+++ b/tools/mod/go.mod
@@ -1,39 +1,39 @@
 module go.etcd.io/etcd/tools/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 require (
-	github.com/alexfalkowski/gocovmerge v1.3.18
+	github.com/alexfalkowski/gocovmerge v1.4.0
 	github.com/appscodelabs/license-bill-of-materials v0.0.0-20220707232035-6018e0c5287c
 	github.com/chzchzchz/goword v0.0.0-20170907005317-a9744cb52b03
 	github.com/cloudflare/cfssl v1.6.5
 	github.com/gogo/protobuf v1.3.2
-	github.com/golangci/golangci-lint v1.63.4
+	github.com/golangci/golangci-lint v1.64.6
 	github.com/google/addlicense v1.1.1
 	github.com/google/yamlfmt v0.16.0
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3
 	go.etcd.io/gofail v0.2.0
 	go.etcd.io/protodoc v0.0.0-20180829002748-484ab544e116
 	go.etcd.io/raft/v3 v3.6.0
 	gotest.tools/gotestsum v1.12.0
 	gotest.tools/v3 v3.5.2
-	honnef.co/go/tools v0.5.1
+	honnef.co/go/tools v0.6.0
 )
 
 require (
-	4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
-	4d63.com/gochecknoglobals v0.2.1 // indirect
-	github.com/4meepo/tagalign v1.4.1 // indirect
+	4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
+	4d63.com/gochecknoglobals v0.2.2 // indirect
+	github.com/4meepo/tagalign v1.4.2 // indirect
 	github.com/Abirdcfly/dupword v0.1.3 // indirect
 	github.com/Antonboom/errname v1.0.0 // indirect
 	github.com/Antonboom/nilnil v1.0.1 // indirect
 	github.com/Antonboom/testifylint v1.5.2 // indirect
 	github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
-	github.com/Crocmagnon/fatcontext v0.5.3 // indirect
+	github.com/Crocmagnon/fatcontext v0.7.1 // indirect
 	github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
-	github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 // indirect
+	github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 // indirect
 	github.com/Masterminds/semver/v3 v3.3.0 // indirect
 	github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect
 	github.com/akhenakh/hunspellgo v0.0.0-20160221122622-9db38fa26e19 // indirect
@@ -41,21 +41,21 @@ require (
 	github.com/alexkohler/nakedret/v2 v2.0.5 // indirect
 	github.com/alexkohler/prealloc v1.0.0 // indirect
 	github.com/alingse/asasalint v0.0.11 // indirect
-	github.com/alingse/nilnesserr v0.1.1 // indirect
+	github.com/alingse/nilnesserr v0.1.2 // indirect
 	github.com/ashanbrown/forbidigo v1.6.0 // indirect
 	github.com/ashanbrown/makezero v1.2.0 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/bitfield/gotestdox v0.2.2 // indirect
 	github.com/bkielbasa/cyclop v1.2.3 // indirect
 	github.com/blizzy78/varnamelen v0.8.0 // indirect
-	github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
+	github.com/bmatcuk/doublestar/v4 v4.8.1 // indirect
 	github.com/bombsimon/wsl/v4 v4.5.0 // indirect
 	github.com/braydonk/yaml v0.9.0 // indirect
 	github.com/breml/bidichk v0.3.2 // indirect
 	github.com/breml/errchkjson v0.4.0 // indirect
 	github.com/butuzov/ireturn v0.3.1 // indirect
 	github.com/butuzov/mirror v1.3.0 // indirect
-	github.com/catenacyber/perfsprint v0.7.1 // indirect
+	github.com/catenacyber/perfsprint v0.8.2 // indirect
 	github.com/ccojocar/zxcvbn-go v1.0.2 // indirect
 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
 	github.com/charithe/durationcheck v0.0.10 // indirect
@@ -72,8 +72,8 @@ require (
 	github.com/firefart/nonamedreturns v1.0.5 // indirect
 	github.com/fsnotify/fsnotify v1.7.0 // indirect
 	github.com/fzipp/gocyclo v0.6.0 // indirect
-	github.com/ghostiam/protogetter v0.3.8 // indirect
-	github.com/go-critic/go-critic v0.11.5 // indirect
+	github.com/ghostiam/protogetter v0.3.9 // indirect
+	github.com/go-critic/go-critic v0.12.0 // indirect
 	github.com/go-logr/logr v1.4.2 // indirect
 	github.com/go-sql-driver/mysql v1.7.1 // indirect
 	github.com/go-toolsmith/astcast v1.1.0 // indirect
@@ -90,18 +90,18 @@ require (
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
 	github.com/golangci/go-printf-func-name v0.1.0 // indirect
-	github.com/golangci/gofmt v0.0.0-20241223200906-057b0627d9b9 // indirect
+	github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect
 	github.com/golangci/misspell v0.6.0 // indirect
 	github.com/golangci/plugin-module-register v0.1.1 // indirect
-	github.com/golangci/revgrep v0.5.3 // indirect
+	github.com/golangci/revgrep v0.8.0 // indirect
 	github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect
 	github.com/google/certificate-transparency-go v1.1.7 // indirect
-	github.com/google/go-cmp v0.6.0 // indirect
+	github.com/google/go-cmp v0.7.0 // indirect
 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
 	github.com/gordonklaus/ineffassign v0.1.0 // indirect
 	github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
-	github.com/gostaticanalysis/comment v1.4.2 // indirect
-	github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
+	github.com/gostaticanalysis/comment v1.5.0 // indirect
+	github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
 	github.com/gostaticanalysis/nilerr v0.1.1 // indirect
 	github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
 	github.com/hashicorp/go-version v1.7.0 // indirect
@@ -115,17 +115,17 @@ require (
 	github.com/jmhodges/clock v1.2.0 // indirect
 	github.com/jmoiron/sqlx v1.3.5 // indirect
 	github.com/julz/importas v0.2.0 // indirect
-	github.com/karamaru-alpha/copyloopvar v1.1.0 // indirect
-	github.com/kisielk/errcheck v1.8.0 // indirect
+	github.com/karamaru-alpha/copyloopvar v1.2.1 // indirect
+	github.com/kisielk/errcheck v1.9.0 // indirect
 	github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46 // indirect
-	github.com/kkHAIKE/contextcheck v1.1.5 // indirect
+	github.com/kkHAIKE/contextcheck v1.1.6 // indirect
+	github.com/klauspost/compress v1.18.0 // indirect
 	github.com/kulti/thelper v0.6.3 // indirect
 	github.com/kunwardeep/paralleltest v1.0.10 // indirect
-	github.com/kyoh86/exportloopref v0.1.11 // indirect
 	github.com/lasiar/canonicalheader v1.1.2 // indirect
-	github.com/ldez/exptostd v0.3.1 // indirect
-	github.com/ldez/gomoddirectives v0.6.0 // indirect
-	github.com/ldez/grignotin v0.7.0 // indirect
+	github.com/ldez/exptostd v0.4.2 // indirect
+	github.com/ldez/gomoddirectives v0.6.1 // indirect
+	github.com/ldez/grignotin v0.9.0 // indirect
 	github.com/ldez/tagliatelle v0.7.1 // indirect
 	github.com/ldez/usetesting v0.4.2 // indirect
 	github.com/leonklingele/grouper v1.1.2 // indirect
@@ -134,12 +134,12 @@ require (
 	github.com/magiconair/properties v1.8.7 // indirect
 	github.com/maratori/testableexamples v1.0.0 // indirect
 	github.com/maratori/testpackage v1.1.1 // indirect
-	github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect
+	github.com/matoous/godox v1.1.0 // indirect
 	github.com/mattn/go-colorable v0.1.14 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mattn/go-runewidth v0.0.16 // indirect
 	github.com/mattn/go-sqlite3 v1.14.22 // indirect
-	github.com/mgechev/revive v1.5.1 // indirect
+	github.com/mgechev/revive v1.7.0 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/moricho/tparallel v0.3.2 // indirect
@@ -147,13 +147,13 @@ require (
 	github.com/nakabonne/nestif v0.3.1 // indirect
 	github.com/nishanths/exhaustive v0.12.0 // indirect
 	github.com/nishanths/predeclared v0.2.2 // indirect
-	github.com/nunnatsa/ginkgolinter v0.18.4 // indirect
+	github.com/nunnatsa/ginkgolinter v0.19.1 // indirect
 	github.com/olekukonko/tablewriter v0.0.5 // indirect
 	github.com/pelletier/go-toml v1.9.5 // indirect
 	github.com/pelletier/go-toml/v2 v2.2.3 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/polyfloyd/go-errorlint v1.7.0 // indirect
-	github.com/prometheus/client_golang v1.20.5 // indirect
+	github.com/polyfloyd/go-errorlint v1.7.1 // indirect
+	github.com/prometheus/client_golang v1.21.0 // indirect
 	github.com/prometheus/client_model v0.6.1 // indirect
 	github.com/prometheus/common v0.62.0 // indirect
 	github.com/prometheus/procfs v0.15.1 // indirect
@@ -164,7 +164,7 @@ require (
 	github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
 	github.com/raeperd/recvcheck v0.2.0 // indirect
 	github.com/rivo/uniseg v0.4.7 // indirect
-	github.com/rogpeppe/go-internal v1.13.1 // indirect
+	github.com/rogpeppe/go-internal v1.14.1 // indirect
 	github.com/ryancurrah/gomodguard v1.3.5 // indirect
 	github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
 	github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect
@@ -172,16 +172,15 @@ require (
 	github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect
 	github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
 	github.com/sashamelentyev/usestdlibvars v1.28.0 // indirect
-	github.com/securego/gosec/v2 v2.21.4 // indirect
-	github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
+	github.com/securego/gosec/v2 v2.22.1 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
 	github.com/sivchari/containedctx v1.0.3 // indirect
 	github.com/sivchari/tenv v1.12.1 // indirect
 	github.com/sonatard/noctx v0.1.0 // indirect
 	github.com/sourcegraph/go-diff v0.7.0 // indirect
-	github.com/spf13/afero v1.11.0 // indirect
+	github.com/spf13/afero v1.12.0 // indirect
 	github.com/spf13/cast v1.5.0 // indirect
-	github.com/spf13/cobra v1.8.1 // indirect
+	github.com/spf13/cobra v1.9.1 // indirect
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 	github.com/spf13/pflag v1.0.6 // indirect
 	github.com/spf13/viper v1.12.0 // indirect
@@ -190,8 +189,8 @@ require (
 	github.com/stretchr/objx v0.5.2 // indirect
 	github.com/stretchr/testify v1.10.0 // indirect
 	github.com/subosito/gotenv v1.4.1 // indirect
-	github.com/tdakkota/asciicheck v0.3.0 // indirect
-	github.com/tetafro/godot v1.4.20 // indirect
+	github.com/tdakkota/asciicheck v0.4.1 // indirect
+	github.com/tetafro/godot v1.5.0 // indirect
 	github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 // indirect
 	github.com/timonwong/loggercheck v0.10.1 // indirect
 	github.com/tomarrell/wrapcheck/v2 v2.10.0 // indirect
@@ -200,7 +199,7 @@ require (
 	github.com/ultraware/funlen v0.2.0 // indirect
 	github.com/ultraware/whitespace v0.2.0 // indirect
 	github.com/uudashr/gocognit v1.2.0 // indirect
-	github.com/uudashr/iface v1.3.0 // indirect
+	github.com/uudashr/iface v1.3.1 // indirect
 	github.com/weppos/publicsuffix-go v0.30.0 // indirect
 	github.com/xen0n/gosmopolitan v1.2.2 // indirect
 	github.com/yagipy/maintidx v1.0.0 // indirect
@@ -210,22 +209,21 @@ require (
 	github.com/zmap/zlint/v3 v3.5.0 // indirect
 	gitlab.com/bosi/decorder v0.4.2 // indirect
 	go-simpler.org/musttag v0.13.0 // indirect
-	go-simpler.org/sloglint v0.7.2 // indirect
+	go-simpler.org/sloglint v0.9.0 // indirect
 	go.uber.org/automaxprocs v1.6.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	go.uber.org/zap v1.27.0 // indirect
-	golang.org/x/crypto v0.33.0 // indirect
-	golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
-	golang.org/x/exp/typeparams v0.0.0-20241108190413-2d47ceb2692f // indirect
-	golang.org/x/mod v0.22.0 // indirect
-	golang.org/x/net v0.34.0 // indirect
+	golang.org/x/crypto v0.35.0 // indirect
+	golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect
+	golang.org/x/mod v0.23.0 // indirect
+	golang.org/x/net v0.36.0 // indirect
 	golang.org/x/sync v0.11.0 // indirect
 	golang.org/x/sys v0.30.0 // indirect
 	golang.org/x/term v0.29.0 // indirect
 	golang.org/x/text v0.22.0 // indirect
-	golang.org/x/tools v0.29.0 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect
+	golang.org/x/tools v0.30.0 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
 	google.golang.org/grpc v1.70.0 // indirect
 	google.golang.org/protobuf v1.36.5 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
diff --git a/tools/mod/go.sum b/tools/mod/go.sum
index 5f4a20648..abfc6ebd6 100644
--- a/tools/mod/go.sum
+++ b/tools/mod/go.sum
@@ -1,9 +1,9 @@
-4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA=
-4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs=
-4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc=
-4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU=
-github.com/4meepo/tagalign v1.4.1 h1:GYTu2FaPGOGb/xJalcqHeD4il5BiCywyEYZOA55P6J4=
-github.com/4meepo/tagalign v1.4.1/go.mod h1:2H9Yu6sZ67hmuraFgfZkNcg5Py9Ch/Om9l2K/2W1qS4=
+4d63.com/gocheckcompilerdirectives v1.3.0 h1:Ew5y5CtcAAQeTVKUVFrE7EwHMrTO6BggtEj8BZSjZ3A=
+4d63.com/gocheckcompilerdirectives v1.3.0/go.mod h1:ofsJ4zx2QAuIP/NO/NAh1ig6R1Fb18/GI7RVMwz7kAY=
+4d63.com/gochecknoglobals v0.2.2 h1:H1vdnwnMaZdQW/N+NrkT1SZMTBmcwHe9Vq8lJcYYTtU=
+4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=
+github.com/4meepo/tagalign v1.4.2 h1:0hcLHPGMjDyM1gHG58cS73aQF8J4TdVR96TZViorO9E=
+github.com/4meepo/tagalign v1.4.2/go.mod h1:+p4aMyFM+ra7nb41CnFG6aSDXqRxU/w1VQqScKqDARI=
 github.com/Abirdcfly/dupword v0.1.3 h1:9Pa1NuAsZvpFPi9Pqkd93I7LIYRURj+A//dFd5tgBeE=
 github.com/Abirdcfly/dupword v0.1.3/go.mod h1:8VbB2t7e10KRNdwTVoxdBaxla6avbhGzb8sCTygUMhw=
 github.com/Antonboom/errname v1.0.0 h1:oJOOWR07vS1kRusl6YRSlat7HFnb3mSfMl6sDMRoTBA=
@@ -14,12 +14,12 @@ github.com/Antonboom/testifylint v1.5.2 h1:4s3Xhuv5AvdIgbd8wOOEeo0uZG7PbDKQyKY5l
 github.com/Antonboom/testifylint v1.5.2/go.mod h1:vxy8VJ0bc6NavlYqjZfmp6EfqXMtBgQ4+mhCojwC1P8=
 github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=
 github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
-github.com/Crocmagnon/fatcontext v0.5.3 h1:zCh/wjc9oyeF+Gmp+V60wetm8ph2tlsxocgg/J0hOps=
-github.com/Crocmagnon/fatcontext v0.5.3/go.mod h1:XoCQYY1J+XTfyv74qLXvNw4xFunr3L1wkopIIKG7wGM=
+github.com/Crocmagnon/fatcontext v0.7.1 h1:SC/VIbRRZQeQWj/TcQBS6JmrXcfA+BU4OGSVUt54PjM=
+github.com/Crocmagnon/fatcontext v0.7.1/go.mod h1:1wMvv3NXEBJucFGfwOJBxSVWcoIO6emV215SMkW9MFU=
 github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=
 github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
-github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 h1:/fTUt5vmbkAcMBt4YQiuC23cV0kEsN1MVMNqeOW43cU=
-github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0/go.mod h1:ONJg5sxcbsdQQ4pOW8TGdTidT2TMAUy/2Xhr8mrYaao=
+github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 h1:Sz1JIXEcSfhz7fUi7xHnhpIE0thVASYjvosApmHuD2k=
+github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1/go.mod h1:n/LSCXNuIYqVfBlVXyHfMQkZDdp1/mmxfSjADd3z1Zg=
 github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
 github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
 github.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJPdp74zmpA=
@@ -32,16 +32,16 @@ github.com/alecthomas/go-check-sumtype v0.3.1 h1:u9aUvbGINJxLVXiFvHUlPEaD7VDULsr
 github.com/alecthomas/go-check-sumtype v0.3.1/go.mod h1:A8TSiN3UPRw3laIgWEUOHHLPa6/r9MtoigdlP5h3K/E=
 github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
 github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
-github.com/alexfalkowski/gocovmerge v1.3.18 h1:GRJz7uNUHuumvWQtS2zBjDkLdIiCcYE1rfxYYWwYvs8=
-github.com/alexfalkowski/gocovmerge v1.3.18/go.mod h1:TnngCLiVe3kIrJ8v12zHP8aQkRWpjTomZm18uQrRDvE=
+github.com/alexfalkowski/gocovmerge v1.4.0 h1:sKiQYXR4CYdKOxwcZbVVHka0Pv8qADVule33pxcMz0M=
+github.com/alexfalkowski/gocovmerge v1.4.0/go.mod h1:v1ugjLQktGsqJ8WPOooeKvd6eJlucF/wmHBpPp+kals=
 github.com/alexkohler/nakedret/v2 v2.0.5 h1:fP5qLgtwbx9EJE8dGEERT02YwS8En4r9nnZ71RK+EVU=
 github.com/alexkohler/nakedret/v2 v2.0.5/go.mod h1:bF5i0zF2Wo2o4X4USt9ntUWve6JbFv02Ff4vlkmS/VU=
 github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw=
 github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
 github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw=
 github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
-github.com/alingse/nilnesserr v0.1.1 h1:7cYuJewpy9jFNMEA72Q1+3Nm3zKHzg+Q28D5f2bBFUA=
-github.com/alingse/nilnesserr v0.1.1/go.mod h1:1xJPrXonEtX7wyTq8Dytns5P2hNzoWymVUIaKm4HNFg=
+github.com/alingse/nilnesserr v0.1.2 h1:Yf8Iwm3z2hUUrP4muWfW83DF4nE3r1xZ26fGWUKCZlo=
+github.com/alingse/nilnesserr v0.1.2/go.mod h1:1xJPrXonEtX7wyTq8Dytns5P2hNzoWymVUIaKm4HNFg=
 github.com/appscodelabs/license-bill-of-materials v0.0.0-20220707232035-6018e0c5287c h1:xv0ICJ4AO52aNZ+vI2KFUYZBMh7dHvROixZ1vzMMfu8=
 github.com/appscodelabs/license-bill-of-materials v0.0.0-20220707232035-6018e0c5287c/go.mod h1:Y5/1I+0gnnhHKyX4z65mgaGTJ08tnz9WUgkoymA/cws=
 github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8gerOIVIY=
@@ -57,8 +57,8 @@ github.com/bkielbasa/cyclop v1.2.3/go.mod h1:kHTwA9Q0uZqOADdupvcFJQtp/ksSnytRMe8
 github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M=
 github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=
 github.com/bmatcuk/doublestar/v4 v4.0.2/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
-github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
-github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
+github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38=
+github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
 github.com/bombsimon/wsl/v4 v4.5.0 h1:iZRsEvDdyhd2La0FVi5k6tYehpOR/R7qIUjmKk7N74A=
 github.com/bombsimon/wsl/v4 v4.5.0/go.mod h1:NOQ3aLF4nD7N5YPXMruR6ZXDOAqLoM0GEpLwTdvmOSc=
 github.com/braydonk/yaml v0.9.0 h1:ewGMrVmEVpsm3VwXQDR388sLg5+aQ8Yihp6/hc4m+h4=
@@ -71,8 +71,8 @@ github.com/butuzov/ireturn v0.3.1 h1:mFgbEI6m+9W8oP/oDdfA34dLisRFCj2G6o/yiI1yZrY
 github.com/butuzov/ireturn v0.3.1/go.mod h1:ZfRp+E7eJLC0NQmk1Nrm1LOrn/gQlOykv+cVPdiXH5M=
 github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc=
 github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI=
-github.com/catenacyber/perfsprint v0.7.1 h1:PGW5G/Kxn+YrN04cRAZKC+ZuvlVwolYMrIyyTJ/rMmc=
-github.com/catenacyber/perfsprint v0.7.1/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50=
+github.com/catenacyber/perfsprint v0.8.2 h1:+o9zVmCSVa7M4MvabsWvESEhpsMkhfE7k0sHNGL95yw=
+github.com/catenacyber/perfsprint v0.8.2/go.mod h1:q//VWC2fWbcdSLEY1R3l8n0zQCDPdE4IjZwyY1HMunM=
 github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg=
 github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
@@ -89,7 +89,7 @@ github.com/cloudflare/cfssl v1.6.5 h1:46zpNkm6dlNkMZH/wMW22ejih6gIaJbzL2du6vD7Ze
 github.com/cloudflare/cfssl v1.6.5/go.mod h1:Bk1si7sq8h2+yVEDrFJiz3d7Aw+pfjjJSZVaD+Taky4=
 github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA=
 github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/curioswitch/go-reassign v0.3.0 h1:dh3kpQHuADL3cobV/sSGETA8DOv457dwl+fbBAhrQPs=
 github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88=
 github.com/daixiang0/gci v0.13.5 h1:kThgmH1yBmZSBCh1EJVxQ7JsHpm5Oms0AMed/0LaH4c=
@@ -119,10 +119,10 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
 github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
 github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
 github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
-github.com/ghostiam/protogetter v0.3.8 h1:LYcXbYvybUyTIxN2Mj9h6rHrDZBDwZloPoKctWrFyJY=
-github.com/ghostiam/protogetter v0.3.8/go.mod h1:WZ0nw9pfzsgxuRsPOFQomgDVSWtDLJRfQJEhsGbmQMA=
-github.com/go-critic/go-critic v0.11.5 h1:TkDTOn5v7EEngMxu8KbuFqFR43USaaH8XRJLz1jhVYA=
-github.com/go-critic/go-critic v0.11.5/go.mod h1:wu6U7ny9PiaHaZHcvMDmdysMqvDem162Rh3zWTrqk8M=
+github.com/ghostiam/protogetter v0.3.9 h1:j+zlLLWzqLay22Cz/aYwTHKQ88GE2DQ6GkWSYFOI4lQ=
+github.com/ghostiam/protogetter v0.3.9/go.mod h1:WZ0nw9pfzsgxuRsPOFQomgDVSWtDLJRfQJEhsGbmQMA=
+github.com/go-critic/go-critic v0.12.0 h1:iLosHZuye812wnkEz1Xu3aBwn5ocCPfc9yqmFG9pa6w=
+github.com/go-critic/go-critic v0.12.0/go.mod h1:DpE0P6OVc6JzVYzmM5gq5jMU31zLr4am5mB/VfFK64w=
 github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
 github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@@ -168,16 +168,16 @@ github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9
 github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
 github.com/golangci/go-printf-func-name v0.1.0 h1:dVokQP+NMTO7jwO4bwsRwLWeudOVUPPyAKJuzv8pEJU=
 github.com/golangci/go-printf-func-name v0.1.0/go.mod h1:wqhWFH5mUdJQhweRnldEywnR5021wTdZSNgwYceV14s=
-github.com/golangci/gofmt v0.0.0-20241223200906-057b0627d9b9 h1:t5wybL6RtO83VwoMOb7U/Peqe3gGKQlPIC66wXmnkvM=
-github.com/golangci/gofmt v0.0.0-20241223200906-057b0627d9b9/go.mod h1:Ag3L7sh7E28qAp/5xnpMMTuGYqxLZoSaEHZDkZB1RgU=
-github.com/golangci/golangci-lint v1.63.4 h1:bJQFQ3hSfUto597dkL7ipDzOxsGEpiWdLiZ359OWOBI=
-github.com/golangci/golangci-lint v1.63.4/go.mod h1:Hx0B7Lg5/NXbaOHem8+KU+ZUIzMI6zNj/7tFwdnn10I=
+github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d h1:viFft9sS/dxoYY0aiOTsLKO2aZQAPT4nlQCsimGcSGE=
+github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY=
+github.com/golangci/golangci-lint v1.64.6 h1:jOLaQN41IV7bMzXuNC4UnQGll7N1xY6eFDXkXEPGKAs=
+github.com/golangci/golangci-lint v1.64.6/go.mod h1:Wz9q+6EVuqGQ94GQ96RB2mjpcZYTOGhBhbt4O7REPu4=
 github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs=
 github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo=
 github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c=
 github.com/golangci/plugin-module-register v0.1.1/go.mod h1:TTpqoB6KkwOJMV8u7+NyXMrkwwESJLOkfl9TxR1DGFc=
-github.com/golangci/revgrep v0.5.3 h1:3tL7c1XBMtWHHqVpS5ChmiAAoe4PF/d5+ULzV9sLAzs=
-github.com/golangci/revgrep v0.5.3/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k=
+github.com/golangci/revgrep v0.8.0 h1:EZBctwbVd0aMeRnNUsFogoyayvKHyxlV3CdUA46FX2s=
+github.com/golangci/revgrep v0.8.0/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k=
 github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed h1:IURFTjxeTfNFP0hTEi1YKjB/ub8zkpaOqFFMApi2EAs=
 github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed/go.mod h1:XLXN8bNw4CGRPaqgl3bv/lhz7bsGPh4/xSaMTbo2vkQ=
 github.com/google/addlicense v1.1.1 h1:jpVf9qPbU8rz5MxKo7d+RMcNHkqxi4YJi/laauX4aAE=
@@ -190,12 +190,13 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
 github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
-github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA=
-github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
+github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
 github.com/google/yamlfmt v0.16.0 h1:5auoxqdx2CxOb022XGBElFFVH8uE/lAJDCWKRMq4mT8=
@@ -205,17 +206,18 @@ github.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it
 github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=
 github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
 github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
-github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q=
 github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM=
-github.com/gostaticanalysis/forcetypeassert v0.1.0 h1:6eUflI3DiGusXGK6X7cCcIgVCpZ2CiZ1Q7jl6ZxNV70=
-github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak=
+github.com/gostaticanalysis/comment v1.5.0 h1:X82FLl+TswsUMpMh17srGRuKaaXprTaytmEpgnKIDu8=
+github.com/gostaticanalysis/comment v1.5.0/go.mod h1:V6eb3gpCv9GNVqb6amXzEUX3jXLVK/AdA+IrAMSqvEc=
+github.com/gostaticanalysis/forcetypeassert v0.2.0 h1:uSnWrrUEYDr86OCxWa4/Tp2jeYDlogZiZHzGkWFefTk=
+github.com/gostaticanalysis/forcetypeassert v0.2.0/go.mod h1:M5iPavzE9pPqWyeiVXSFghQjljW1+l/Uke3PXHS6ILY=
 github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk=
 github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=
 github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M=
 github.com/gostaticanalysis/testutil v0.5.0 h1:Dq4wT1DdTwTGCQQv3rl3IvD5Ld0E6HiY+3Zh0sUGqw8=
 github.com/gostaticanalysis/testutil v0.5.0/go.mod h1:OLQSbuM6zw2EvCcXTz1lVq5unyoNft372msDY0nY5Hs=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
 github.com/hashicorp/go-immutable-radix/v2 v2.1.0 h1:CUW5RYIcysz+D3B+l1mDeXrQ7fUvGGCwJfdASSzbrfo=
 github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw=
 github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
@@ -243,18 +245,18 @@ github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
 github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
 github.com/julz/importas v0.2.0 h1:y+MJN/UdL63QbFJHws9BVC5RpA2iq0kpjrFajTGivjQ=
 github.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx3xiJY=
-github.com/karamaru-alpha/copyloopvar v1.1.0 h1:x7gNyKcC2vRBO1H2Mks5u1VxQtYvFiym7fCjIP8RPos=
-github.com/karamaru-alpha/copyloopvar v1.1.0/go.mod h1:u7CIfztblY0jZLOQZgH3oYsJzpC2A7S6u/lfgSXHy0k=
+github.com/karamaru-alpha/copyloopvar v1.2.1 h1:wmZaZYIjnJ0b5UoKDjUHrikcV0zuPyyxI4SVplLd2CI=
+github.com/karamaru-alpha/copyloopvar v1.2.1/go.mod h1:nFmMlFNlClC2BPvNaHMdkirmTJxVCY0lhxBtlfOypMM=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
-github.com/kisielk/errcheck v1.8.0 h1:ZX/URYa7ilESY19ik/vBmCn6zdGQLxACwjAcWbHlYlg=
-github.com/kisielk/errcheck v1.8.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ=
+github.com/kisielk/errcheck v1.9.0 h1:9xt1zI9EBfcYBvdU1nVrzMzzUPUtPKs9bVSIM3TAb3M=
+github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46 h1:veS9QfglfvqAw2e+eeNT/SbGySq8ajECXJ9e4fPoLhY=
 github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
-github.com/kkHAIKE/contextcheck v1.1.5 h1:CdnJh63tcDe53vG+RebdpdXJTc9atMgGqdx8LXxiilg=
-github.com/kkHAIKE/contextcheck v1.1.5/go.mod h1:O930cpht4xb1YQpK+1+AgoM3mFsvxr7uyFptcnWTYUA=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/kkHAIKE/contextcheck v1.1.6 h1:7HIyRcnyzxL9Lz06NGhiKvenXq7Zw6Q0UQu/ttjfJCE=
+github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -268,16 +270,14 @@ github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs=
 github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I=
 github.com/kunwardeep/paralleltest v1.0.10 h1:wrodoaKYzS2mdNVnc4/w31YaXFtsc21PCTdvWJ/lDDs=
 github.com/kunwardeep/paralleltest v1.0.10/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY=
-github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ=
-github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA=
 github.com/lasiar/canonicalheader v1.1.2 h1:vZ5uqwvDbyJCnMhmFYimgMZnJMjwljN5VGY0VKbMXb4=
 github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI=
-github.com/ldez/exptostd v0.3.1 h1:90yWWoAKMFHeovTK8uzBms9Ppp8Du/xQ20DRO26Ymrw=
-github.com/ldez/exptostd v0.3.1/go.mod h1:iZBRYaUmcW5jwCR3KROEZ1KivQQp6PHXbDPk9hqJKCQ=
-github.com/ldez/gomoddirectives v0.6.0 h1:Jyf1ZdTeiIB4dd+2n4qw+g4aI9IJ6JyfOZ8BityWvnA=
-github.com/ldez/gomoddirectives v0.6.0/go.mod h1:TuwOGYoPAoENDWQpe8DMqEm5nIfjrxZXmxX/CExWyZ4=
-github.com/ldez/grignotin v0.7.0 h1:vh0dI32WhHaq6LLPZ38g7WxXuZ1+RzyrJ7iPG9JMa8c=
-github.com/ldez/grignotin v0.7.0/go.mod h1:uaVTr0SoZ1KBii33c47O1M8Jp3OP3YDwhZCmzT9GHEk=
+github.com/ldez/exptostd v0.4.2 h1:l5pOzHBz8mFOlbcifTxzfyYbgEmoUqjxLFHZkjlbHXs=
+github.com/ldez/exptostd v0.4.2/go.mod h1:iZBRYaUmcW5jwCR3KROEZ1KivQQp6PHXbDPk9hqJKCQ=
+github.com/ldez/gomoddirectives v0.6.1 h1:Z+PxGAY+217f/bSGjNZr/b2KTXcyYLgiWI6geMBN2Qc=
+github.com/ldez/gomoddirectives v0.6.1/go.mod h1:cVBiu3AHR9V31em9u2kwfMKD43ayN5/XDgr+cdaFaKs=
+github.com/ldez/grignotin v0.9.0 h1:MgOEmjZIVNn6p5wPaGp/0OKWyvq42KnzAt/DAb8O4Ow=
+github.com/ldez/grignotin v0.9.0/go.mod h1:uaVTr0SoZ1KBii33c47O1M8Jp3OP3YDwhZCmzT9GHEk=
 github.com/ldez/tagliatelle v0.7.1 h1:bTgKjjc2sQcsgPiT902+aadvMjCeMHrY7ly2XKFORIk=
 github.com/ldez/tagliatelle v0.7.1/go.mod h1:3zjxUpsNB2aEZScWiZTHrAXOl1x25t3cRmzfK1mlo2I=
 github.com/ldez/usetesting v0.4.2 h1:J2WwbrFGk3wx4cZwSMiCQQ00kjGR0+tuuyW0Lqm4lwA=
@@ -295,8 +295,8 @@ github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s
 github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE=
 github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04=
 github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc=
-github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE=
-github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
+github.com/matoous/godox v1.1.0 h1:W5mqwbyWrwZv6OQ5Z1a/DHGMOvXYCBP3+Ht7KMoJhq4=
+github.com/matoous/godox v1.1.0/go.mod h1:jgE/3fUXiTurkdHOLT5WEkThTSuE7yxHv5iWPa80afs=
 github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
 github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
@@ -313,8 +313,8 @@ github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh
 github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
 github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
 github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
-github.com/mgechev/revive v1.5.1 h1:hE+QPeq0/wIzJwOphdVyUJ82njdd8Khp4fUIHGZHW3M=
-github.com/mgechev/revive v1.5.1/go.mod h1:lC9AhkJIBs5zwx8wkudyHrU+IJkrEKmpCmGMnIJPk4o=
+github.com/mgechev/revive v1.7.0 h1:JyeQ4yO5K8aZhIKf5rec56u0376h8AlKNQEmjfkjKlY=
+github.com/mgechev/revive v1.7.0/go.mod h1:qZnwcNhoguE58dfi96IJeSTPeZQejNeoMQLUZGi4SW4=
 github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
@@ -331,14 +331,14 @@ github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhK
 github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=
 github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
 github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
-github.com/nunnatsa/ginkgolinter v0.18.4 h1:zmX4KUR+6fk/vhUFt8DOP6KwznekhkmVSzzVJve2vyM=
-github.com/nunnatsa/ginkgolinter v0.18.4/go.mod h1:AMEane4QQ6JwFz5GgjI5xLUM9S/CylO+UyM97fN2iBI=
+github.com/nunnatsa/ginkgolinter v0.19.1 h1:mjwbOlDQxZi9Cal+KfbEJTCz327OLNfwNvoZ70NJ+c4=
+github.com/nunnatsa/ginkgolinter v0.19.1/go.mod h1:jkQ3naZDmxaZMXPWaS9rblH+i+GWXQCaS/JFIWcOH2s=
 github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
-github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
-github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
-github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
-github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=
+github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
+github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
+github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
+github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
 github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
 github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU=
@@ -353,12 +353,12 @@ github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNH
 github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/polyfloyd/go-errorlint v1.7.0 h1:Zp6lzCK4hpBDj8y8a237YK4EPrMXQWvOe3nGoH4pFrU=
-github.com/polyfloyd/go-errorlint v1.7.0/go.mod h1:dGWKu85mGHnegQ2SWpEybFityCg3j7ZbwsVUxAOk9gY=
+github.com/polyfloyd/go-errorlint v1.7.1 h1:RyLVXIbosq1gBdk/pChWA8zWYLsq9UEw7a1L5TVMCnA=
+github.com/polyfloyd/go-errorlint v1.7.1/go.mod h1:aXjNb1x2TNhoLsk26iv1yl7a+zTnXPhwEMtEXukiLR8=
 github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
-github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
-github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
+github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
 github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
 github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
@@ -381,8 +381,8 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
 github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
 github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
 github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/ryancurrah/gomodguard v1.3.5 h1:cShyguSwUEeC0jS7ylOiG/idnd1TpJ1LfHGpV3oJmPU=
 github.com/ryancurrah/gomodguard v1.3.5/go.mod h1:MXlEPQRxgfPQa62O8wzK3Ozbkv9Rkqr+wKjSxTdsNJE=
@@ -398,10 +398,8 @@ github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tM
 github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=
 github.com/sashamelentyev/usestdlibvars v1.28.0 h1:jZnudE2zKCtYlGzLVreNp5pmCdOxXUzwsMDBkR21cyQ=
 github.com/sashamelentyev/usestdlibvars v1.28.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8=
-github.com/securego/gosec/v2 v2.21.4 h1:Le8MSj0PDmOnHJgUATjD96PaXRvCpKC+DGJvwyy0Mlk=
-github.com/securego/gosec/v2 v2.21.4/go.mod h1:Jtb/MwRQfRxCXyCm1rfM1BEiiiTfUOdyzzAhlr6lUTA=
-github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU=
-github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
+github.com/securego/gosec/v2 v2.22.1 h1:IcBt3TpI5Y9VN1YlwjSpM2cHu0i3Iw52QM+PQeg7jN8=
+github.com/securego/gosec/v2 v2.22.1/go.mod h1:4bb95X4Jz7VSEPdVjC0hD7C/yR6kdeUBvCPOy9gDQ0g=
 github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
 github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
 github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -417,12 +415,12 @@ github.com/sonatard/noctx v0.1.0 h1:JjqOc2WN16ISWAjAk8M5ej0RfExEXtkEyExl2hLW+OM=
 github.com/sonatard/noctx v0.1.0/go.mod h1:0RvBxqY8D4j9cTTTWE8ylt2vqj2EPI8fHmrxHdsaZ2c=
 github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0=
 github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
-github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
-github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
+github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
+github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
 github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
 github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
 github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@@ -453,14 +451,14 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
 github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
-github.com/tdakkota/asciicheck v0.3.0 h1:LqDGgZdholxZMaJgpM6b0U9CFIjDCbFdUF00bDnBKOQ=
-github.com/tdakkota/asciicheck v0.3.0/go.mod h1:KoJKXuX/Z/lt6XzLo8WMBfQGzak0SrAKZlvRr4tg8Ac=
+github.com/tdakkota/asciicheck v0.4.1 h1:bm0tbcmi0jezRA2b5kg4ozmMuGAFotKI3RZfrhfovg8=
+github.com/tdakkota/asciicheck v0.4.1/go.mod h1:0k7M3rCfRXb0Z6bwgvkEIMleKH3kXNz9UqJ9Xuqopr8=
 github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA=
 github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=
 github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag=
 github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
-github.com/tetafro/godot v1.4.20 h1:z/p8Ek55UdNvzt4TFn2zx2KscpW4rWqcnUrdmvWJj7E=
-github.com/tetafro/godot v1.4.20/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio=
+github.com/tetafro/godot v1.5.0 h1:aNwfVI4I3+gdxjMgYPus9eHmoBeJIbnajOyqZYStzuw=
+github.com/tetafro/godot v1.5.0/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio=
 github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 h1:y4mJRFlM6fUyPhoXuFg/Yu02fg/nIPFMOY8tOqppoFg=
 github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460=
 github.com/timonwong/loggercheck v0.10.1 h1:uVZYClxQFpw55eh+PIoqM7uAOHMrhVcDoWDery9R8Lg=
@@ -477,8 +475,8 @@ github.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSW
 github.com/ultraware/whitespace v0.2.0/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8=
 github.com/uudashr/gocognit v1.2.0 h1:3BU9aMr1xbhPlvJLSydKwdLN3tEUUrzPSSM8S4hDYRA=
 github.com/uudashr/gocognit v1.2.0/go.mod h1:k/DdKPI6XBZO1q7HgoV2juESI2/Ofj9AcHPZhBBdrTU=
-github.com/uudashr/iface v1.3.0 h1:zwPch0fs9tdh9BmL5kcgSpvnObV+yHjO4JjVBl8IA10=
-github.com/uudashr/iface v1.3.0/go.mod h1:4QvspiRd3JLPAEXBQ9AiZpLbJlrWWgRChOKDJEuQTdg=
+github.com/uudashr/iface v1.3.1 h1:bA51vmVx1UIhiIsQFSNq6GZ6VPTk3WNMZgRiCe9R29U=
+github.com/uudashr/iface v1.3.1/go.mod h1:4QvspiRd3JLPAEXBQ9AiZpLbJlrWWgRChOKDJEuQTdg=
 github.com/weppos/publicsuffix-go v0.12.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k=
 github.com/weppos/publicsuffix-go v0.13.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k=
 github.com/weppos/publicsuffix-go v0.30.0 h1:QHPZ2GRu/YE7cvejH9iyavPOkVCB4dNxp2ZvtT+vQLY=
@@ -516,8 +514,8 @@ go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ=
 go-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28=
 go-simpler.org/musttag v0.13.0 h1:Q/YAW0AHvaoaIbsPj3bvEI5/QFP7w696IMUpnKXQfCE=
 go-simpler.org/musttag v0.13.0/go.mod h1:FTzIGeK6OkKlUDVpj0iQUXZLUO1Js9+mvykDQy9C5yM=
-go-simpler.org/sloglint v0.7.2 h1:Wc9Em/Zeuu7JYpl+oKoYOsQSy2X560aVueCW/m6IijY=
-go-simpler.org/sloglint v0.7.2/go.mod h1:US+9C80ppl7VsThQclkM7BkCHQAzuz8kHLsW3ppuluo=
+go-simpler.org/sloglint v0.9.0 h1:/40NQtjRx9txvsB/RN022KsUJU+zaaSb/9q9BSefSrE=
+go-simpler.org/sloglint v0.9.0/go.mod h1:G/OrAF6uxj48sHahCzrbarVMptL2kjWTaUeC8+fOGww=
 go.etcd.io/gofail v0.2.0 h1:p19drv16FKK345a09a1iubchlw/vmRuksmRzgBIGjcA=
 go.etcd.io/gofail v0.2.0/go.mod h1:nL3ILMGfkXTekKI3clMBNazKnjUZjYLKmBHzsVAnC1o=
 go.etcd.io/protodoc v0.0.0-20180829002748-484ab544e116 h1:QQiUXlqz+d96jyNG71NE+IGTgOK6Xlhdx+PzvfbLHlQ=
@@ -546,14 +544,14 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
 golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
 golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
 golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
-golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
-golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
+golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
+golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
 golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
 golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
-golang.org/x/exp/typeparams v0.0.0-20241108190413-2d47ceb2692f h1:WTyX8eCCyfdqiPYkRGm0MqElSfYFH3yR1+rl/mct9sA=
-golang.org/x/exp/typeparams v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac h1:TSSpLIG4v+p0rPv1pNOQtl1I8knsO4S9trOxNMOLVP4=
+golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -568,9 +566,8 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
-golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
+golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -585,7 +582,6 @@ golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
@@ -595,8 +591,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
 golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
 golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
+golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -648,7 +644,6 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
@@ -666,7 +661,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
@@ -676,8 +670,6 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
 golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
 golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
@@ -694,23 +686,22 @@ golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
 golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
-golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
 golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
 golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
 golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
 golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
-golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
-golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
+golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
+golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
 google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
 google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
 google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
@@ -733,8 +724,8 @@ gotest.tools/gotestsum v1.12.0/go.mod h1:fAvqkSptospfSbQw26CTYzNwnsE/ztqLeyhP0h6
 gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
 gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
 gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
-honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I=
-honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs=
+honnef.co/go/tools v0.6.0 h1:TAODvD3knlq75WCp2nyGJtT4LeRV/o7NN9nYPeVJXf8=
+honnef.co/go/tools v0.6.0/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=
 k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
 k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
 mvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU=
diff --git a/tools/rw-heatmaps/go.mod b/tools/rw-heatmaps/go.mod
index 97e7120cf..8d031cd04 100644
--- a/tools/rw-heatmaps/go.mod
+++ b/tools/rw-heatmaps/go.mod
@@ -1,11 +1,11 @@
 module go.etcd.io/etcd/tools/rw-heatmaps/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 require (
-	github.com/spf13/cobra v1.8.1
+	github.com/spf13/cobra v1.9.1
 	github.com/spf13/pflag v1.0.6
 	gonum.org/v1/plot v0.14.0
 )
diff --git a/tools/rw-heatmaps/go.sum b/tools/rw-heatmaps/go.sum
index 9e0e13676..2face21be 100644
--- a/tools/rw-heatmaps/go.sum
+++ b/tools/rw-heatmaps/go.sum
@@ -9,7 +9,7 @@ github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyR
 github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=
 github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY=
 github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ=
 github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
 github.com/go-fonts/latin-modern v0.3.1 h1:/cT8A7uavYKvglYXvrdDw4oS5ZLkcOU22fa2HJ1/JVM=
@@ -28,9 +28,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
diff --git a/tools/testgrid-analysis/go.mod b/tools/testgrid-analysis/go.mod
index 27a2278c7..078d8759f 100644
--- a/tools/testgrid-analysis/go.mod
+++ b/tools/testgrid-analysis/go.mod
@@ -1,25 +1,26 @@
 module go.etcd.io/etcd/tools/testgrid-analysis/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 require (
 	github.com/GoogleCloudPlatform/testgrid v0.0.173
 	github.com/google/go-github/v60 v60.0.0
-	github.com/spf13/cobra v1.8.1
+	github.com/spf13/cobra v1.9.1
 	google.golang.org/protobuf v1.36.5
 )
 
 require (
+	github.com/google/go-cmp v0.7.0 // indirect
 	github.com/google/go-querystring v1.1.0 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/spf13/pflag v1.0.6 // indirect
 	go.opentelemetry.io/otel v1.34.0 // indirect
 	go.opentelemetry.io/otel/sdk v1.34.0 // indirect
-	golang.org/x/net v0.34.0 // indirect
+	golang.org/x/net v0.36.0 // indirect
 	golang.org/x/sys v0.30.0 // indirect
 	golang.org/x/text v0.22.0 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
 	google.golang.org/grpc v1.70.0 // indirect
 )
diff --git a/tools/testgrid-analysis/go.sum b/tools/testgrid-analysis/go.sum
index 79f96a52d..70c5eed0c 100644
--- a/tools/testgrid-analysis/go.sum
+++ b/tools/testgrid-analysis/go.sum
@@ -809,7 +809,7 @@ github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWH
 github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -935,8 +935,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/go-github/v60 v60.0.0 h1:oLG98PsLauFvvu4D/YPxq374jhSxFYdzQGNCyONLfn8=
 github.com/google/go-github/v60 v60.0.0/go.mod h1:ByhX2dP9XT9o/ll2yXAu2VD8l5eNVg8hD4Cr0S/LmQk=
 github.com/google/go-pkcs11 v0.2.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY=
@@ -1140,8 +1140,8 @@ github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTd
 github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
 github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
 github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@@ -1336,8 +1336,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
+golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1841,8 +1841,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go.
 google.golang.org/genproto/googleapis/rpc v0.0.0-20230720185612-659f7aaaa771/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
 google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=



Test patch:
diff --git a/client/pkg/fileutil/lock_test.go b/client/pkg/fileutil/lock_test.go
index 0c5da9855..ea449e1cf 100644
--- a/client/pkg/fileutil/lock_test.go
+++ b/client/pkg/fileutil/lock_test.go
@@ -23,7 +23,7 @@ import (
 )
 
 func TestLockAndUnlock(t *testing.T) {
-	f, err := os.CreateTemp("", "lock")
+	f, err := os.CreateTemp(t.TempDir(), "lock")
 	require.NoError(t, err)
 	f.Close()
 	defer func() {
diff --git a/client/v3/yaml/config_test.go b/client/v3/yaml/config_test.go
index 4d23f2749..f4c68c999 100644
--- a/client/v3/yaml/config_test.go
+++ b/client/v3/yaml/config_test.go
@@ -73,7 +73,7 @@ func TestConfigFromFile(t *testing.T) {
 	}
 
 	for i, tt := range tests {
-		tmpfile, err := os.CreateTemp("", "clientcfg")
+		tmpfile, err := os.CreateTemp(t.TempDir(), "clientcfg")
 		if err != nil {
 			log.Fatal(err)
 		}
diff --git a/server/embed/config_test.go b/server/embed/config_test.go
index 54247382f..872d649ea 100644
--- a/server/embed/config_test.go
+++ b/server/embed/config_test.go
@@ -615,7 +615,7 @@ func compareSlices(slice1, slice2 []string) bool {
 }
 
 func mustCreateCfgFile(t *testing.T, b []byte) *os.File {
-	tmpfile, err := os.CreateTemp("", "servercfg")
+	tmpfile, err := os.CreateTemp(t.TempDir(), "servercfg")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -843,7 +843,7 @@ func TestLogRotation(t *testing.T) {
 			logOutputs:        []string{"/tmp/path"},
 			logRotationConfig: `{"maxsize": true}`,
 			wantErr:           true,
-			wantErrMsg:        errors.New("invalid log rotation config: json: cannot unmarshal bool into Go struct field logRotationConfig.maxsize of type int"),
+			wantErrMsg:        errors.New("invalid log rotation config: json: cannot unmarshal bool into Go struct field logRotationConfig.Logger.maxsize of type int"),
 		},
 		{
 			name:              "improperly formatted logger config",
diff --git a/server/etcdmain/config_test.go b/server/etcdmain/config_test.go
index 56ff9766a..514f93ca0 100644
--- a/server/etcdmain/config_test.go
+++ b/server/etcdmain/config_test.go
@@ -1244,7 +1244,7 @@ func generateCfgsFromFileAndCmdLine(t *testing.T, yc any, cmdLineArgs []string)
 }
 
 func mustCreateCfgFile(t *testing.T, b []byte) *os.File {
-	tmpfile, err := os.CreateTemp("", "servercfg")
+	tmpfile, err := os.CreateTemp(t.TempDir(), "servercfg")
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/server/etcdserver/server_test.go b/server/etcdserver/server_test.go
index d3f379837..c7843ebcf 100644
--- a/server/etcdserver/server_test.go
+++ b/server/etcdserver/server_test.go
@@ -24,12 +24,15 @@ import (
 	"os"
 	"path/filepath"
 	"reflect"
+	"strings"
 	"sync"
 	"testing"
 	"time"
 
 	"github.com/coreos/go-semver/semver"
 	"github.com/golang/protobuf/proto"
+	"github.com/prometheus/client_golang/prometheus"
+	ptestutil "github.com/prometheus/client_golang/prometheus/testutil"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"go.uber.org/zap"
@@ -42,6 +45,7 @@ import (
 	"go.etcd.io/etcd/client/pkg/v3/testutil"
 	"go.etcd.io/etcd/client/pkg/v3/types"
 	"go.etcd.io/etcd/client/pkg/v3/verify"
+	"go.etcd.io/etcd/pkg/v3/featuregate"
 	"go.etcd.io/etcd/pkg/v3/idutil"
 	"go.etcd.io/etcd/pkg/v3/notify"
 	"go.etcd.io/etcd/pkg/v3/pbutil"
@@ -1683,3 +1687,30 @@ func TestIsActive(t *testing.T) {
 		require.Equal(t, tc.expectActive, s.isActive())
 	}
 }
+
+func TestAddFeatureGateMetrics(t *testing.T) {
+	const testAlphaGate featuregate.Feature = "TestAlpha"
+	const testBetaGate featuregate.Feature = "TestBeta"
+	const testGAGate featuregate.Feature = "TestGA"
+
+	featuremap := map[featuregate.Feature]featuregate.FeatureSpec{
+		testGAGate:    {Default: true, PreRelease: featuregate.GA},
+		testAlphaGate: {Default: true, PreRelease: featuregate.Alpha},
+		testBetaGate:  {Default: false, PreRelease: featuregate.Beta},
+	}
+	fg := featuregate.New("test", zaptest.NewLogger(t))
+	fg.Add(featuremap)
+
+	addFeatureGateMetrics(fg, serverFeatureEnabled)
+
+	expected := `# HELP etcd_server_feature_enabled Whether or not a feature is enabled. 1 is enabled, 0 is not.
+	# TYPE etcd_server_feature_enabled gauge
+	etcd_server_feature_enabled{name="AllAlpha",stage="ALPHA"} 0
+	etcd_server_feature_enabled{name="AllBeta",stage="BETA"} 0
+	etcd_server_feature_enabled{name="TestAlpha",stage="ALPHA"} 1
+	etcd_server_feature_enabled{name="TestBeta",stage="BETA"} 0
+	etcd_server_feature_enabled{name="TestGA",stage=""} 1
+	`
+	err := ptestutil.GatherAndCompare(prometheus.DefaultGatherer, strings.NewReader(expected), "etcd_server_feature_enabled")
+	require.NoErrorf(t, err, "unexpected metric collection result: \n%s", err)
+}
diff --git a/tests/common/lease_test.go b/tests/common/lease_test.go
index afb27c330..1cebc5775 100644
--- a/tests/common/lease_test.go
+++ b/tests/common/lease_test.go
@@ -122,7 +122,7 @@ func TestLeaseGrantTimeToLiveExpired(t *testing.T) {
 
 	for _, tc := range clusterTestCases() {
 		t.Run(tc.name, func(t *testing.T) {
-			ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+			ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
 			defer cancel()
 			clus := testRunner.NewCluster(ctx, t, config.WithClusterConfig(tc.config))
 			defer clus.Close()
@@ -139,7 +139,23 @@ func TestLeaseGrantTimeToLiveExpired(t *testing.T) {
 				require.NoError(t, err)
 				require.Equal(t, int64(1), getResp.Count)
 
-				time.Sleep(3 * time.Second)
+				// FIXME: When leader changes, old leader steps
+				// back to follower and ignores the lease revoking.
+				// The new leader will restart TTL counting. If so,
+				// we should call time.Sleep again and wait for revoking.
+				// It can't avoid flakey but reduce flakey possiblility.
+				for i := 0; i < 3; i++ {
+					currentLeader := clus.WaitLeader(t)
+					t.Logf("[%d] current leader index %d", i, currentLeader)
+
+					time.Sleep(3 * time.Second)
+
+					newLeader := clus.WaitLeader(t)
+					if newLeader == currentLeader {
+						break
+					}
+					t.Logf("[%d] leader changed, new leader index %d", i, newLeader)
+				}
 
 				ttlResp, err := cc.TimeToLive(ctx, leaseResp.ID, config.LeaseOption{})
 				require.NoError(t, err)
@@ -159,7 +175,7 @@ func TestLeaseGrantKeepAliveOnce(t *testing.T) {
 
 	for _, tc := range clusterTestCases() {
 		t.Run(tc.name, func(t *testing.T) {
-			ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+			ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
 			defer cancel()
 			clus := testRunner.NewCluster(ctx, t, config.WithClusterConfig(tc.config))
 			defer clus.Close()
@@ -172,7 +188,23 @@ func TestLeaseGrantKeepAliveOnce(t *testing.T) {
 				_, err = cc.KeepAliveOnce(ctx, leaseResp.ID)
 				require.NoError(t, err)
 
-				time.Sleep(2 * time.Second) // Wait for the original lease to expire
+				// FIXME: When leader changes, old leader steps
+				// back to follower and ignores the lease revoking.
+				// The new leader will restart TTL counting. If so,
+				// we should call time.Sleep again and wait for revoking.
+				// It can't avoid flakey but reduce flakey possiblility.
+				for i := 0; i < 3; i++ {
+					currentLeader := clus.WaitLeader(t)
+					t.Logf("[%d] current leader index %d", i, currentLeader)
+
+					time.Sleep(2 * time.Second)
+
+					newLeader := clus.WaitLeader(t)
+					if newLeader == currentLeader {
+						break
+					}
+					t.Logf("[%d] leader changed, new leader index %d", i, newLeader)
+				}
 
 				ttlResp, err := cc.TimeToLive(ctx, leaseResp.ID, config.LeaseOption{})
 				require.NoError(t, err)
diff --git a/tests/e2e/cluster_downgrade_test.go b/tests/e2e/cluster_downgrade_test.go
index 3533adfff..0d80f0c4b 100644
--- a/tests/e2e/cluster_downgrade_test.go
+++ b/tests/e2e/cluster_downgrade_test.go
@@ -25,6 +25,7 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
+	pb "go.etcd.io/etcd/api/v3/etcdserverpb"
 	"go.etcd.io/etcd/api/v3/version"
 	"go.etcd.io/etcd/client/pkg/v3/fileutil"
 	"go.etcd.io/etcd/client/pkg/v3/types"
@@ -51,6 +52,10 @@ func TestDowngradeUpgradeClusterOf1(t *testing.T) {
 	testDowngradeUpgrade(t, 1, 1, false, noCancellation)
 }
 
+func TestDowngradeUpgrade2InClusterOf3(t *testing.T) {
+	testDowngradeUpgrade(t, 2, 3, false, noCancellation)
+}
+
 func TestDowngradeUpgradeClusterOf3(t *testing.T) {
 	testDowngradeUpgrade(t, 3, 3, false, noCancellation)
 }
@@ -128,6 +133,9 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
 		time.Sleep(etcdserver.HealthInterval)
 	}
 
+	t.Log("Downgrade should be disabled")
+	e2e.ValidateDowngradeInfo(t, epc, &pb.DowngradeInfo{Enabled: false})
+
 	t.Log("Adding member to test membership, but a learner avoid breaking quorum")
 	resp, err := cc.MemberAddAsLearner(context.Background(), "fake1", []string{"http://127.0.0.1:1001"})
 	require.NoError(t, err)
@@ -150,6 +158,10 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
 		return // No need to perform downgrading, end the test here
 	}
 	e2e.DowngradeEnable(t, epc, lastVersion)
+
+	t.Log("Downgrade should be enabled")
+	e2e.ValidateDowngradeInfo(t, epc, &pb.DowngradeInfo{Enabled: true, TargetVersion: lastClusterVersion.String()})
+
 	if triggerCancellation == cancelRightAfterEnable {
 		t.Logf("Cancelling downgrade right after enabling (no node is downgraded yet)")
 		e2e.DowngradeCancel(t, epc)
@@ -162,10 +174,10 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
 	t.Logf("Elect members for operations on members: %v", membersToChange)
 
 	t.Logf("Starting downgrade process to %q", lastVersionStr)
-	err = e2e.DowngradeUpgradeMembersByID(t, nil, epc, membersToChange, currentVersion, lastClusterVersion)
+	err = e2e.DowngradeUpgradeMembersByID(t, nil, epc, membersToChange, true, currentVersion, lastClusterVersion)
 	require.NoError(t, err)
 	if len(membersToChange) == len(epc.Procs) {
-		e2e.AssertProcessLogs(t, leader(t, epc), "the cluster has been downgraded")
+		e2e.AssertProcessLogs(t, epc.Procs[epc.WaitLeader(t)], "the cluster has been downgraded")
 	}
 
 	t.Log("Downgrade complete")
@@ -198,10 +210,19 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
 	beforeMembers, beforeKV = getMembersAndKeys(t, cc)
 
 	t.Logf("Starting upgrade process to %q", currentVersionStr)
-	err = e2e.DowngradeUpgradeMembersByID(t, nil, epc, membersToChange, lastClusterVersion, currentVersion)
+	downgradeEnabled := triggerCancellation == noCancellation && numberOfMembersToDowngrade < clusterSize
+	err = e2e.DowngradeUpgradeMembersByID(t, nil, epc, membersToChange, downgradeEnabled, lastClusterVersion, currentVersion)
 	require.NoError(t, err)
 	t.Log("Upgrade complete")
 
+	if downgradeEnabled {
+		t.Log("Downgrade should be still enabled")
+		e2e.ValidateDowngradeInfo(t, epc, &pb.DowngradeInfo{Enabled: true, TargetVersion: lastClusterVersion.String()})
+	} else {
+		t.Log("Downgrade should be disabled")
+		e2e.ValidateDowngradeInfo(t, epc, &pb.DowngradeInfo{Enabled: false})
+	}
+
 	afterMembers, afterKV = getMembersAndKeys(t, cc)
 	assert.Equal(t, beforeKV.Kvs, afterKV.Kvs)
 	assert.Equal(t, beforeMembers.Members, afterMembers.Members)
@@ -224,27 +245,6 @@ func newCluster(t *testing.T, clusterSize int, snapshotCount uint64) *e2e.EtcdPr
 	return epc
 }
 
-func leader(t *testing.T, epc *e2e.EtcdProcessCluster) e2e.EtcdProcess {
-	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
-	defer cancel()
-	for i := 0; i < len(epc.Procs); i++ {
-		endpoints := epc.Procs[i].EndpointsGRPC()
-		cli, err := clientv3.New(clientv3.Config{
-			Endpoints:   endpoints,
-			DialTimeout: 3 * time.Second,
-		})
-		require.NoError(t, err)
-		defer cli.Close()
-		resp, err := cli.Status(ctx, endpoints[0])
-		require.NoError(t, err)
-		if resp.Header.GetMemberId() == resp.Leader {
-			return epc.Procs[i]
-		}
-	}
-	t.Fatal("Leader not found")
-	return nil
-}
-
 func generateSnapshot(t *testing.T, snapshotCount uint64, cc *e2e.EtcdctlV3) {
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
diff --git a/tests/e2e/ctl_v3_snapshot_test.go b/tests/e2e/ctl_v3_snapshot_test.go
index c9dc03235..d66249a54 100644
--- a/tests/e2e/ctl_v3_snapshot_test.go
+++ b/tests/e2e/ctl_v3_snapshot_test.go
@@ -163,13 +163,9 @@ func TestIssue6361(t *testing.T) { testIssue6361(t) }
 // TestIssue6361 ensures new member that starts with snapshot correctly
 // syncs up with other members and serve correct data.
 func testIssue6361(t *testing.T) {
-	{
-		// This tests is pretty flaky on semaphoreci as of 2021-01-10.
-		// TODO: Remove when the flakiness source is identified.
-		oldenv := os.Getenv("EXPECT_DEBUG")
-		defer os.Setenv("EXPECT_DEBUG", oldenv)
-		os.Setenv("EXPECT_DEBUG", "1")
-	}
+	// This tests is pretty flaky on semaphoreci as of 2021-01-10.
+	// TODO: Remove when the flakiness source is identified.
+	t.Setenv("EXPECT_DEBUG", "1")
 
 	e2e.BeforeTest(t)
 
diff --git a/tests/e2e/v3_curl_watch_test.go b/tests/e2e/v3_curl_watch_test.go
index 5e7bc8de9..f6ced632c 100644
--- a/tests/e2e/v3_curl_watch_test.go
+++ b/tests/e2e/v3_curl_watch_test.go
@@ -15,8 +15,11 @@
 package e2e
 
 import (
+	"context"
 	"encoding/json"
+	"syscall"
 	"testing"
+	"time"
 
 	"github.com/stretchr/testify/require"
 
@@ -46,3 +49,26 @@ func testCurlV3Watch(cx ctlCtx) {
 	// expects "bar", timeout after 2 seconds since stream waits forever
 	require.ErrorContains(cx.t, e2e.CURLPost(cx.epc, e2e.CURLReq{Endpoint: "/v3/watch", Value: wstr, Expected: expect.ExpectedResponse{Value: `"YmFy"`}, Timeout: 2}), "unexpected exit code")
 }
+
+// TestCurlWatchIssue19509 tries to reproduce https://github.com/etcd-io/etcd/issues/19509
+func TestCurlWatchIssue19509(t *testing.T) {
+	e2e.BeforeTest(t)
+
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	epc, err := e2e.NewEtcdProcessCluster(ctx, t, e2e.WithConfig(e2e.NewConfigClientTLS()), e2e.WithClusterSize(1))
+	require.NoError(t, err)
+	defer epc.Close()
+
+	curlCmdAndArgs := e2e.CURLPrefixArgsCluster(epc.Cfg, epc.Procs[0], "POST", e2e.CURLReq{Endpoint: "/v3/watch", Timeout: 3})
+	for i := 0; i < 10; i++ {
+		curlProc, err := e2e.SpawnCmd(curlCmdAndArgs, nil)
+		require.NoError(t, err)
+		time.Sleep(100 * time.Millisecond)
+
+		_ = curlProc.Signal(syscall.SIGKILL)
+		_ = curlProc.Close()
+
+		require.Truef(t, epc.Procs[0].IsRunning(), "etcdserver already exited after %d curl watch requests", i+1)
+	}
+}
diff --git a/tests/framework/e2e/cluster.go b/tests/framework/e2e/cluster.go
index 60bd2b595..5af564072 100644
--- a/tests/framework/e2e/cluster.go
+++ b/tests/framework/e2e/cluster.go
@@ -28,6 +28,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/coreos/go-semver/semver"
 	"go.uber.org/zap"
 	"go.uber.org/zap/zaptest"
 
@@ -711,6 +712,21 @@ func (cfg *EtcdProcessClusterConfig) binaryPath(i int) string {
 	return execPath
 }
 
+func (epc *EtcdProcessCluster) MinServerVersion() (*semver.Version, error) {
+	var minVersion *semver.Version
+	for _, member := range epc.Procs {
+		ver, err := GetVersionFromBinary(member.Config().ExecPath)
+		if err != nil {
+			return nil, fmt.Errorf("failed to get version from member %s binary: %w", member.Config().Name, err)
+		}
+
+		if minVersion == nil || ver.LessThan(*minVersion) {
+			minVersion = ver
+		}
+	}
+	return minVersion, nil
+}
+
 func values(cfg embed.Config) map[string]string {
 	fs := flag.NewFlagSet("etcd", flag.ContinueOnError)
 	cfg.AddFlags(fs)
diff --git a/tests/framework/e2e/downgrade.go b/tests/framework/e2e/downgrade.go
index 231f03d87..1f9e71ec2 100644
--- a/tests/framework/e2e/downgrade.go
+++ b/tests/framework/e2e/downgrade.go
@@ -27,7 +27,9 @@ import (
 	"github.com/stretchr/testify/require"
 	"go.uber.org/zap"
 
+	pb "go.etcd.io/etcd/api/v3/etcdserverpb"
 	"go.etcd.io/etcd/api/v3/version"
+	"go.etcd.io/etcd/server/v3/etcdserver"
 	"go.etcd.io/etcd/tests/v3/framework/testutils"
 )
 
@@ -46,7 +48,6 @@ func DowngradeEnable(t *testing.T, epc *EtcdProcessCluster, ver *semver.Version)
 			Server:  OffsetMinor(ver, 1).String(),
 			Storage: ver.String(),
 		})
-		AssertProcessLogs(t, epc.Procs[i], "The server is ready to downgrade")
 	}
 
 	t.Log("Cluster is ready for downgrade")
@@ -82,14 +83,59 @@ func DowngradeCancel(t *testing.T, epc *EtcdProcessCluster) {
 	t.Log("Cluster downgrade cancellation is completed")
 }
 
-func DowngradeUpgradeMembers(t *testing.T, lg *zap.Logger, clus *EtcdProcessCluster, numberOfMembersToChange int, currentVersion, targetVersion *semver.Version) error {
+func ValidateDowngradeInfo(t *testing.T, clus *EtcdProcessCluster, expected *pb.DowngradeInfo) {
+	cfg := clus.Cfg
+
+	for i := 0; i < len(clus.Procs); i++ {
+		member := clus.Procs[i]
+		mc := member.Etcdctl()
+		mName := member.Config().Name
+
+		testutils.ExecuteWithTimeout(t, 1*time.Minute, func() {
+			for {
+				statuses, err := mc.Status(context.Background())
+				if err != nil {
+					cfg.Logger.Warn("failed to get member status and retrying",
+						zap.Error(err),
+						zap.String("member", mName))
+
+					time.Sleep(time.Second)
+					continue
+				}
+
+				require.Lenf(t, statuses, 1, "member %s", mName)
+				got := (*pb.StatusResponse)(statuses[0]).GetDowngradeInfo()
+
+				if got.GetEnabled() == expected.GetEnabled() && got.GetTargetVersion() == expected.GetTargetVersion() {
+					cfg.Logger.Info("DowngradeInfo match", zap.String("member", mName))
+					break
+				}
+
+				cfg.Logger.Warn("DowngradeInfo didn't match retrying",
+					zap.String("member", mName),
+					zap.Dict("expected",
+						zap.Bool("Enabled", expected.GetEnabled()),
+						zap.String("TargetVersion", expected.GetTargetVersion()),
+					),
+					zap.Dict("got",
+						zap.Bool("Enabled", got.GetEnabled()),
+						zap.String("TargetVersion", got.GetTargetVersion()),
+					),
+				)
+				time.Sleep(time.Second)
+			}
+		})
+	}
+}
+
+func DowngradeUpgradeMembers(t *testing.T, lg *zap.Logger, clus *EtcdProcessCluster, numberOfMembersToChange int, downgradeEnabled bool, currentVersion, targetVersion *semver.Version) error {
 	membersToChange := rand.Perm(len(clus.Procs))[:numberOfMembersToChange]
 	t.Logf("Elect members for operations on members: %v", membersToChange)
 
-	return DowngradeUpgradeMembersByID(t, lg, clus, membersToChange, currentVersion, targetVersion)
+	return DowngradeUpgradeMembersByID(t, lg, clus, membersToChange, downgradeEnabled, currentVersion, targetVersion)
 }
 
-func DowngradeUpgradeMembersByID(t *testing.T, lg *zap.Logger, clus *EtcdProcessCluster, membersToChange []int, currentVersion, targetVersion *semver.Version) error {
+func DowngradeUpgradeMembersByID(t *testing.T, lg *zap.Logger, clus *EtcdProcessCluster, membersToChange []int, downgradeEnabled bool, currentVersion, targetVersion *semver.Version) error {
 	if lg == nil {
 		lg = clus.lg
 	}
@@ -100,7 +146,6 @@ func DowngradeUpgradeMembersByID(t *testing.T, lg *zap.Logger, clus *EtcdProcess
 		opString = "downgrading"
 		newExecPath = BinPath.EtcdLastRelease
 	}
-
 	for _, memberID := range membersToChange {
 		member := clus.Procs[memberID]
 		if member.Config().ExecPath == newExecPath {
@@ -117,11 +162,33 @@ func DowngradeUpgradeMembersByID(t *testing.T, lg *zap.Logger, clus *EtcdProcess
 			return err
 		}
 	}
+
+	t.Log("Waiting health interval to make sure the leader propagates version to new processes")
+	time.Sleep(etcdserver.HealthInterval)
+
 	lg.Info("Validating versions")
+	clusterVersion := targetVersion
+	if !isDowngrade {
+		if downgradeEnabled {
+			// If the downgrade isn't cancelled yet, then the cluster
+			// version will always stay at the lower version, no matter
+			// what's the binary version of each member.
+			clusterVersion = currentVersion
+		} else {
+			// If the downgrade has already been cancelled, then the
+			// cluster version is the minimal server version.
+			minVer, err := clus.MinServerVersion()
+			if err != nil {
+				return fmt.Errorf("failed to get min server version: %w", err)
+			}
+			clusterVersion = minVer
+		}
+	}
+
 	for _, memberID := range membersToChange {
 		member := clus.Procs[memberID]
 		ValidateVersion(t, clus.Cfg, member, version.Versions{
-			Cluster: targetVersion.String(),
+			Cluster: clusterVersion.String(),
 			Server:  targetVersion.String(),
 		})
 	}
diff --git a/tests/go.mod b/tests/go.mod
index 0f568fae2..88dabf481 100644
--- a/tests/go.mod
+++ b/tests/go.mod
@@ -1,8 +1,8 @@
 module go.etcd.io/etcd/tests/v3
 
-go 1.23
+go 1.24
 
-toolchain go1.23.6
+toolchain go1.24.1
 
 replace (
 	go.etcd.io/etcd/api/v3 => ../api
@@ -19,11 +19,11 @@ require (
 	github.com/anishathalye/porcupine v1.0.0
 	github.com/coreos/go-semver v0.3.1
 	github.com/golang/protobuf v1.5.4
-	github.com/google/go-cmp v0.6.0
+	github.com/google/go-cmp v0.7.0
 	github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
 	github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1
-	github.com/prometheus/client_golang v1.20.5
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3
+	github.com/prometheus/client_golang v1.21.0
 	github.com/prometheus/client_model v0.6.1
 	github.com/prometheus/common v0.62.0
 	github.com/soheilhy/cmux v0.1.5
@@ -44,7 +44,7 @@ require (
 	go.opentelemetry.io/otel/trace v1.34.0
 	go.opentelemetry.io/proto/otlp v1.5.0
 	go.uber.org/zap v1.27.0
-	golang.org/x/crypto v0.33.0
+	golang.org/x/crypto v0.35.0
 	golang.org/x/sync v0.11.0
 	golang.org/x/time v0.10.0
 	google.golang.org/grpc v1.70.0
@@ -57,7 +57,7 @@ require (
 	github.com/bgentry/speakeasy v0.2.0 // indirect
 	github.com/cenkalti/backoff/v4 v4.3.0 // indirect
 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
-	github.com/cheggaaa/pb/v3 v3.1.6 // indirect
+	github.com/cheggaaa/pb/v3 v3.1.7 // indirect
 	github.com/coreos/go-systemd/v22 v22.5.0 // indirect
 	github.com/creack/pty v1.1.18 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
@@ -74,7 +74,7 @@ require (
 	github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/jonboulle/clockwork v0.5.0 // indirect
-	github.com/klauspost/compress v1.17.9 // indirect
+	github.com/klauspost/compress v1.18.0 // indirect
 	github.com/mattn/go-colorable v0.1.14 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mattn/go-runewidth v0.0.16 // indirect
@@ -84,7 +84,7 @@ require (
 	github.com/prometheus/procfs v0.15.1 // indirect
 	github.com/rivo/uniseg v0.4.7 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
-	github.com/spf13/cobra v1.8.1 // indirect
+	github.com/spf13/cobra v1.9.1 // indirect
 	github.com/spf13/pflag v1.0.6 // indirect
 	github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
 	github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
@@ -94,11 +94,11 @@ require (
 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect
 	go.opentelemetry.io/otel/metric v1.34.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
-	golang.org/x/net v0.34.0 // indirect
+	golang.org/x/net v0.36.0 // indirect
 	golang.org/x/sys v0.30.0 // indirect
 	golang.org/x/text v0.22.0 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
diff --git a/tests/go.sum b/tests/go.sum
index 17b1b8b41..0bb1c1773 100644
--- a/tests/go.sum
+++ b/tests/go.sum
@@ -13,8 +13,8 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cheggaaa/pb/v3 v3.1.6 h1:h0x+vd7EiUohAJ29DJtJy+SNAc55t/elW3jCD086EXk=
-github.com/cheggaaa/pb/v3 v3.1.6/go.mod h1:urxmfVtaxT+9aWk92DbsvXFZtNSWQSO5TRAp+MJ3l1s=
+github.com/cheggaaa/pb/v3 v3.1.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI=
+github.com/cheggaaa/pb/v3 v3.1.7/go.mod h1:/Ji89zfVPeC/u5j8ukD0MBPHt2bzTYp74lQ7KlgFWTQ=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA=
@@ -23,7 +23,7 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr
 github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
 github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
 github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -63,8 +63,8 @@ github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
 github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
@@ -75,16 +75,16 @@ github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpS
 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk=
 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
 github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -108,8 +108,8 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
-github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
+github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
 github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
@@ -120,17 +120,16 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
 github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
 github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
 github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -184,8 +183,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
-golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
+golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
+golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -201,8 +200,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
+golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -243,10 +242,10 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o=
-google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
+google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
 google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
diff --git a/tests/integration/clientv3/examples/example_cluster_test.go b/tests/integration/clientv3/examples/example_cluster_test.go
index 1d2da78c7..3a83e8a99 100644
--- a/tests/integration/clientv3/examples/example_cluster_test.go
+++ b/tests/integration/clientv3/examples/example_cluster_test.go
@@ -22,12 +22,12 @@ import (
 	clientv3 "go.etcd.io/etcd/client/v3"
 )
 
-func mockCluster_memberList() {
+func mockClusterMemberList() {
 	fmt.Println("members: 3")
 }
 
 func ExampleCluster_memberList() {
-	forUnitTestsRunInMockedContext(mockCluster_memberList, func() {
+	forUnitTestsRunInMockedContext(mockClusterMemberList, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -46,13 +46,13 @@ func ExampleCluster_memberList() {
 	// Output: members: 3
 }
 
-func mockCluster_memberAdd() {
+func mockClusterMemberAdd() {
 	fmt.Println("added member.PeerURLs: [http://localhost:32380]")
 	fmt.Println("members count: 4")
 }
 
 func ExampleCluster_memberAdd() {
-	forUnitTestsRunInMockedContext(mockCluster_memberAdd, func() {
+	forUnitTestsRunInMockedContext(mockClusterMemberAdd, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -81,13 +81,13 @@ func ExampleCluster_memberAdd() {
 	// members count: 4
 }
 
-func mockCluster_memberAddAsLearner() {
+func mockClusterMemberAddAsLearner() {
 	fmt.Println("members count: 4")
 	fmt.Println("added member.IsLearner: true")
 }
 
 func ExampleCluster_memberAddAsLearner() {
-	forUnitTestsRunInMockedContext(mockCluster_memberAddAsLearner, func() {
+	forUnitTestsRunInMockedContext(mockClusterMemberAddAsLearner, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -116,10 +116,10 @@ func ExampleCluster_memberAddAsLearner() {
 	// added member.IsLearner: true
 }
 
-func mockCluster_memberRemove() {}
+func mockClusterMemberRemove() {}
 
 func ExampleCluster_memberRemove() {
-	forUnitTestsRunInMockedContext(mockCluster_memberRemove, func() {
+	forUnitTestsRunInMockedContext(mockClusterMemberRemove, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -147,10 +147,10 @@ func ExampleCluster_memberRemove() {
 	})
 }
 
-func mockCluster_memberUpdate() {}
+func mockClusterMemberUpdate() {}
 
 func ExampleCluster_memberUpdate() {
-	forUnitTestsRunInMockedContext(mockCluster_memberUpdate, func() {
+	forUnitTestsRunInMockedContext(mockClusterMemberUpdate, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
diff --git a/tests/integration/clientv3/examples/example_kv_test.go b/tests/integration/clientv3/examples/example_kv_test.go
index e4fa4bf5f..235404b67 100644
--- a/tests/integration/clientv3/examples/example_kv_test.go
+++ b/tests/integration/clientv3/examples/example_kv_test.go
@@ -16,6 +16,7 @@ package clientv3_test
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"log"
 
@@ -23,10 +24,10 @@ import (
 	clientv3 "go.etcd.io/etcd/client/v3"
 )
 
-func mockKV_put() {}
+func mockKVPut() {}
 
 func ExampleKV_put() {
-	forUnitTestsRunInMockedContext(mockKV_put, func() {
+	forUnitTestsRunInMockedContext(mockKVPut, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -46,12 +47,12 @@ func ExampleKV_put() {
 	// Output:
 }
 
-func mockKV_putErrorHandling() {
+func mockKVPutErrorHandling() {
 	fmt.Println("client-side error: etcdserver: key is not provided")
 }
 
 func ExampleKV_putErrorHandling() {
-	forUnitTestsRunInMockedContext(mockKV_putErrorHandling, func() {
+	forUnitTestsRunInMockedContext(mockKVPutErrorHandling, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -65,14 +66,13 @@ func ExampleKV_putErrorHandling() {
 		_, err = cli.Put(ctx, "", "sample_value")
 		cancel()
 		if err != nil {
-			switch err {
-			case context.Canceled:
+			if errors.Is(err, context.Canceled) {
 				fmt.Printf("ctx is canceled by another routine: %v\n", err)
-			case context.DeadlineExceeded:
+			} else if errors.Is(err, context.DeadlineExceeded) {
 				fmt.Printf("ctx is attached with a deadline is exceeded: %v\n", err)
-			case rpctypes.ErrEmptyKey:
+			} else if errors.Is(err, rpctypes.ErrEmptyKey) {
 				fmt.Printf("client-side error: %v\n", err)
-			default:
+			} else {
 				fmt.Printf("bad cluster endpoints, which are not etcd servers: %v\n", err)
 			}
 		}
@@ -80,12 +80,12 @@ func ExampleKV_putErrorHandling() {
 	// Output: client-side error: etcdserver: key is not provided
 }
 
-func mockKV_get() {
+func mockKVGet() {
 	fmt.Println("foo : bar")
 }
 
 func ExampleKV_get() {
-	forUnitTestsRunInMockedContext(mockKV_get, func() {
+	forUnitTestsRunInMockedContext(mockKVGet, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -113,12 +113,12 @@ func ExampleKV_get() {
 	// Output: foo : bar
 }
 
-func mockKV_getWithRev() {
+func mockKVGetWithRev() {
 	fmt.Println("foo : bar1")
 }
 
 func ExampleKV_getWithRev() {
-	forUnitTestsRunInMockedContext(mockKV_getWithRev, func() {
+	forUnitTestsRunInMockedContext(mockKVGetWithRev, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -150,14 +150,14 @@ func ExampleKV_getWithRev() {
 	// Output: foo : bar1
 }
 
-func mockKV_getSortedPrefix() {
+func mockKVGetSortedPrefix() {
 	fmt.Println(`key_2 : value`)
 	fmt.Println(`key_1 : value`)
 	fmt.Println(`key_0 : value`)
 }
 
 func ExampleKV_getSortedPrefix() {
-	forUnitTestsRunInMockedContext(mockKV_getSortedPrefix, func() {
+	forUnitTestsRunInMockedContext(mockKVGetSortedPrefix, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -192,12 +192,12 @@ func ExampleKV_getSortedPrefix() {
 	// key_0 : value
 }
 
-func mockKV_delete() {
+func mockKVDelete() {
 	fmt.Println("Deleted all keys: true")
 }
 
 func ExampleKV_delete() {
-	forUnitTestsRunInMockedContext(mockKV_delete, func() {
+	forUnitTestsRunInMockedContext(mockKVDelete, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -228,10 +228,10 @@ func ExampleKV_delete() {
 	// Deleted all keys: true
 }
 
-func mockKV_compact() {}
+func mockKVCompact() {}
 
 func ExampleKV_compact() {
-	forUnitTestsRunInMockedContext(mockKV_compact, func() {
+	forUnitTestsRunInMockedContext(mockKVCompact, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -259,12 +259,12 @@ func ExampleKV_compact() {
 	// Output:
 }
 
-func mockKV_txn() {
+func mockKVTxn() {
 	fmt.Println("key : XYZ")
 }
 
 func ExampleKV_txn() {
-	forUnitTestsRunInMockedContext(mockKV_txn, func() {
+	forUnitTestsRunInMockedContext(mockKVTxn, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -306,10 +306,10 @@ func ExampleKV_txn() {
 	// Output: key : XYZ
 }
 
-func mockKV_do() {}
+func mockKVDo() {}
 
 func ExampleKV_do() {
-	forUnitTestsRunInMockedContext(mockKV_do, func() {
+	forUnitTestsRunInMockedContext(mockKVDo, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
diff --git a/tests/integration/clientv3/examples/example_lease_test.go b/tests/integration/clientv3/examples/example_lease_test.go
index b0e6c5ef3..f55e8314b 100644
--- a/tests/integration/clientv3/examples/example_lease_test.go
+++ b/tests/integration/clientv3/examples/example_lease_test.go
@@ -22,11 +22,11 @@ import (
 	clientv3 "go.etcd.io/etcd/client/v3"
 )
 
-func mockLease_grant() {
+func mockLeaseGrant() {
 }
 
 func ExampleLease_grant() {
-	forUnitTestsRunInMockedContext(mockLease_grant, func() {
+	forUnitTestsRunInMockedContext(mockLeaseGrant, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -51,12 +51,12 @@ func ExampleLease_grant() {
 	// Output:
 }
 
-func mockLease_revoke() {
+func mockLeaseRevoke() {
 	fmt.Println("number of keys: 0")
 }
 
 func ExampleLease_revoke() {
-	forUnitTestsRunInMockedContext(mockLease_revoke, func() {
+	forUnitTestsRunInMockedContext(mockLeaseRevoke, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -91,12 +91,12 @@ func ExampleLease_revoke() {
 	// Output: number of keys: 0
 }
 
-func mockLease_keepAlive() {
+func mockLeaseKeepAlive() {
 	fmt.Println("ttl: 5")
 }
 
 func ExampleLease_keepAlive() {
-	forUnitTestsRunInMockedContext(mockLease_keepAlive, func() {
+	forUnitTestsRunInMockedContext(mockLeaseKeepAlive, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -132,12 +132,12 @@ func ExampleLease_keepAlive() {
 	// Output: ttl: 5
 }
 
-func mockLease_keepAliveOnce() {
+func mockLeaseKeepAliveOnce() {
 	fmt.Println("ttl: 5")
 }
 
 func ExampleLease_keepAliveOnce() {
-	forUnitTestsRunInMockedContext(mockLease_keepAliveOnce, func() {
+	forUnitTestsRunInMockedContext(mockLeaseKeepAliveOnce, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
diff --git a/tests/integration/clientv3/examples/example_maintenance_test.go b/tests/integration/clientv3/examples/example_maintenance_test.go
index ff545e8de..2c901475a 100644
--- a/tests/integration/clientv3/examples/example_maintenance_test.go
+++ b/tests/integration/clientv3/examples/example_maintenance_test.go
@@ -21,10 +21,10 @@ import (
 	clientv3 "go.etcd.io/etcd/client/v3"
 )
 
-func mockMaintenance_status() {}
+func mockMaintenanceStatus() {}
 
 func ExampleMaintenance_status() {
-	forUnitTestsRunInMockedContext(mockMaintenance_status, func() {
+	forUnitTestsRunInMockedContext(mockMaintenanceStatus, func() {
 		for _, ep := range exampleEndpoints() {
 			cli, err := clientv3.New(clientv3.Config{
 				Endpoints:   []string{ep},
@@ -44,10 +44,10 @@ func ExampleMaintenance_status() {
 	// Output:
 }
 
-func mockMaintenance_defragment() {}
+func mockMaintenanceDefragment() {}
 
 func ExampleMaintenance_defragment() {
-	forUnitTestsRunInMockedContext(mockMaintenance_defragment, func() {
+	forUnitTestsRunInMockedContext(mockMaintenanceDefragment, func() {
 		for _, ep := range exampleEndpoints() {
 			cli, err := clientv3.New(clientv3.Config{
 				Endpoints:   []string{ep},
diff --git a/tests/integration/clientv3/examples/example_metrics_test.go b/tests/integration/clientv3/examples/example_metrics_test.go
index 75b47e53d..d467c8281 100644
--- a/tests/integration/clientv3/examples/example_metrics_test.go
+++ b/tests/integration/clientv3/examples/example_metrics_test.go
@@ -31,12 +31,12 @@ import (
 	clientv3 "go.etcd.io/etcd/client/v3"
 )
 
-func mockClient_metrics() {
+func mockClientMetrics() {
 	fmt.Println(`grpc_client_started_total{grpc_method="Range",grpc_service="etcdserverpb.KV",grpc_type="unary"} 1`)
 }
 
 func ExampleClient_metrics() {
-	forUnitTestsRunInMockedContext(mockClient_metrics, func() {
+	forUnitTestsRunInMockedContext(mockClientMetrics, func() {
 		clientMetrics := grpcprom.NewClientMetrics()
 		prometheus.Register(clientMetrics)
 		cli, err := clientv3.New(clientv3.Config{
diff --git a/tests/integration/clientv3/examples/example_test.go b/tests/integration/clientv3/examples/example_test.go
index b9b8be461..166f4fbd2 100644
--- a/tests/integration/clientv3/examples/example_test.go
+++ b/tests/integration/clientv3/examples/example_test.go
@@ -22,10 +22,10 @@ import (
 	clientv3 "go.etcd.io/etcd/client/v3"
 )
 
-func mockConfig_insecure() {}
+func mockConfigInsecure() {}
 
 func ExampleConfig_insecure() {
-	forUnitTestsRunInMockedContext(mockConfig_insecure, func() {
+	forUnitTestsRunInMockedContext(mockConfigInsecure, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -46,10 +46,10 @@ func ExampleConfig_insecure() {
 	// Output:
 }
 
-func mockConfig_withTLS() {}
+func mockConfigWithTLS() {}
 
 func ExampleConfig_withTLS() {
-	forUnitTestsRunInMockedContext(mockConfig_withTLS, func() {
+	forUnitTestsRunInMockedContext(mockConfigWithTLS, func() {
 		tlsInfo := transport.TLSInfo{
 			CertFile:      "/tmp/test-certs/test-name-1.pem",
 			KeyFile:       "/tmp/test-certs/test-name-1-key.pem",
diff --git a/tests/integration/clientv3/examples/example_watch_test.go b/tests/integration/clientv3/examples/example_watch_test.go
index ac44f8ca3..c78d1e7f8 100644
--- a/tests/integration/clientv3/examples/example_watch_test.go
+++ b/tests/integration/clientv3/examples/example_watch_test.go
@@ -23,12 +23,12 @@ import (
 	clientv3 "go.etcd.io/etcd/client/v3"
 )
 
-func mockWatcher_watch() {
+func mockWatcherWatch() {
 	fmt.Println(`PUT "foo" : "bar"`)
 }
 
 func ExampleWatcher_watch() {
-	forUnitTestsRunInMockedContext(mockWatcher_watch, func() {
+	forUnitTestsRunInMockedContext(mockWatcherWatch, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -48,12 +48,12 @@ func ExampleWatcher_watch() {
 	// PUT "foo" : "bar"
 }
 
-func mockWatcher_watchWithPrefix() {
+func mockWatcherWatchWithPrefix() {
 	fmt.Println(`PUT "foo1" : "bar"`)
 }
 
 func ExampleWatcher_watchWithPrefix() {
-	forUnitTestsRunInMockedContext(mockWatcher_watchWithPrefix, func() {
+	forUnitTestsRunInMockedContext(mockWatcherWatchWithPrefix, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -73,14 +73,14 @@ func ExampleWatcher_watchWithPrefix() {
 	// PUT "foo1" : "bar"
 }
 
-func mockWatcher_watchWithRange() {
+func mockWatcherWatchWithRange() {
 	fmt.Println(`PUT "foo1" : "bar1"`)
 	fmt.Println(`PUT "foo2" : "bar2"`)
 	fmt.Println(`PUT "foo3" : "bar3"`)
 }
 
 func ExampleWatcher_watchWithRange() {
-	forUnitTestsRunInMockedContext(mockWatcher_watchWithRange, func() {
+	forUnitTestsRunInMockedContext(mockWatcherWatchWithRange, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
@@ -121,12 +121,12 @@ func ExampleWatcher_watchWithRange() {
 	// PUT "foo3" : "bar3"
 }
 
-func mockWatcher_watchWithProgressNotify() {
+func mockWatcherWatchWithProgressNotify() {
 	fmt.Println(`wresp.IsProgressNotify: true`)
 }
 
 func ExampleWatcher_watchWithProgressNotify() {
-	forUnitTestsRunInMockedContext(mockWatcher_watchWithProgressNotify, func() {
+	forUnitTestsRunInMockedContext(mockWatcherWatchWithProgressNotify, func() {
 		cli, err := clientv3.New(clientv3.Config{
 			Endpoints:   exampleEndpoints(),
 			DialTimeout: dialTimeout,
diff --git a/tests/integration/clientv3/lease/lease_test.go b/tests/integration/clientv3/lease/lease_test.go
index 943a169e3..eaf4a75ff 100644
--- a/tests/integration/clientv3/lease/lease_test.go
+++ b/tests/integration/clientv3/lease/lease_test.go
@@ -189,7 +189,7 @@ func TestLeaseKeepAlive(t *testing.T) {
 	}
 }
 
-func TestLeaseKeepAliveOneSecond(t *testing.T) {
+func TestLeaseKeepAliveSeconds(t *testing.T) {
 	integration2.BeforeTest(t)
 
 	clus := integration2.NewCluster(t, &integration2.ClusterConfig{Size: 1})
@@ -197,7 +197,7 @@ func TestLeaseKeepAliveOneSecond(t *testing.T) {
 
 	cli := clus.Client(0)
 
-	resp, err := cli.Grant(context.Background(), 1)
+	resp, err := cli.Grant(context.Background(), 3)
 	if err != nil {
 		t.Errorf("failed to create lease %v", err)
 	}
@@ -208,7 +208,7 @@ func TestLeaseKeepAliveOneSecond(t *testing.T) {
 
 	for i := 0; i < 3; i++ {
 		if _, ok := <-rc; !ok {
-			t.Errorf("chan is closed, want not closed")
+			t.Errorf("[%d] chan is closed, want not closed", i)
 		}
 	}
 }
diff --git a/tests/integration/hashkv_test.go b/tests/integration/hashkv_test.go
index 26d5dfaf0..2aa8cc69e 100644
--- a/tests/integration/hashkv_test.go
+++ b/tests/integration/hashkv_test.go
@@ -19,7 +19,6 @@ import (
 	"net"
 	"net/http"
 	"testing"
-	"time"
 
 	"github.com/stretchr/testify/require"
 
@@ -78,8 +77,6 @@ func (tc hashTestCase) Defrag(ctx context.Context) error {
 }
 
 func (tc hashTestCase) Compact(ctx context.Context, rev int64) error {
-	_, err := tc.Client.Compact(ctx, rev)
-	// Wait for compaction to be compacted
-	time.Sleep(50 * time.Millisecond)
+	_, err := tc.Client.Compact(ctx, rev, clientv3.WithCompactPhysical())
 	return err
 }
diff --git a/tests/integration/v3_lease_test.go b/tests/integration/v3_lease_test.go
index e255567d5..532e94f31 100644
--- a/tests/integration/v3_lease_test.go
+++ b/tests/integration/v3_lease_test.go
@@ -1031,7 +1031,7 @@ func acquireLeaseAndKey(clus *integration.Cluster, key string) (int64, error) {
 		return 0, err
 	}
 	if lresp.Error != "" {
-		return 0, fmt.Errorf(lresp.Error)
+		return 0, errors.New(lresp.Error)
 	}
 	// attach to key
 	put := &pb.PutRequest{Key: []byte(key), Lease: lresp.ID}
diff --git a/tests/robustness/failpoint/cluster.go b/tests/robustness/failpoint/cluster.go
index 780e0c006..eb6190368 100644
--- a/tests/robustness/failpoint/cluster.go
+++ b/tests/robustness/failpoint/cluster.go
@@ -174,7 +174,7 @@ func (f memberDowngrade) Inject(ctx context.Context, t *testing.T, lg *zap.Logge
 	time.Sleep(etcdserver.HealthInterval)
 	e2e.DowngradeEnable(t, clus, lastVersion)
 
-	err = e2e.DowngradeUpgradeMembers(t, lg, clus, numberOfMembersToDowngrade, currentVersion, lastVersion)
+	err = e2e.DowngradeUpgradeMembers(t, lg, clus, numberOfMembersToDowngrade, true, currentVersion, lastVersion)
 	time.Sleep(etcdserver.HealthInterval)
 	return nil, err
 }
@@ -228,13 +228,20 @@ func (f memberDowngradeUpgrade) Inject(ctx context.Context, t *testing.T, lg *za
 
 	e2e.DowngradeEnable(t, clus, lastVersion)
 	// downgrade all members first
-	err = e2e.DowngradeUpgradeMembers(t, lg, clus, len(clus.Procs), currentVersion, lastVersion)
+	err = e2e.DowngradeUpgradeMembers(t, lg, clus, len(clus.Procs), true, currentVersion, lastVersion)
 	if err != nil {
 		return nil, err
 	}
+
+	// NOTE: By default, the leader can cancel the downgrade once all members
+	// have reached the target version. However, determining the final stable
+	// cluster version after an upgrade can be challenging. To ensure stability,
+	// we should wait for leader to cancel downgrade process.
+	e2e.AssertProcessLogs(t, clus.Procs[clus.WaitLeader(t)], "the cluster has been downgraded")
+
 	// partial upgrade the cluster
 	numberOfMembersToUpgrade := rand.Int()%len(clus.Procs) + 1
-	err = e2e.DowngradeUpgradeMembers(t, lg, clus, numberOfMembersToUpgrade, lastVersion, currentVersion)
+	err = e2e.DowngradeUpgradeMembers(t, lg, clus, numberOfMembersToUpgrade, false, lastVersion, currentVersion)
 	time.Sleep(etcdserver.HealthInterval)
 	return nil, err
 }
diff --git a/tests/robustness/validate/patch_history.go b/tests/robustness/validate/patch_history.go
index 5ec3bd2ae..7a0658fab 100644
--- a/tests/robustness/validate/patch_history.go
+++ b/tests/robustness/validate/patch_history.go
@@ -26,9 +26,9 @@ import (
 func patchLinearizableOperations(reports []report.ClientReport, persistedRequests []model.EtcdRequest) []porcupine.Operation {
 	allOperations := relevantOperations(reports)
 	putRevision := putRevision(reports)
-	putReturnTime := putReturnTime(allOperations, reports, persistedRequests)
-	clientPutCount := countClientPuts(reports)
 	persistedPutCount := countPersistedPuts(persistedRequests)
+	putReturnTime := uniquePutReturnTime(allOperations, reports, persistedRequests, persistedPutCount)
+	clientPutCount := countClientPuts(reports)
 	return patchOperations(allOperations, putRevision, putReturnTime, clientPutCount, persistedPutCount)
 }
 
@@ -155,7 +155,7 @@ func hasUniqueWriteOperation(ops []model.EtcdOperation, clientRequestCount map[k
 	return false
 }
 
-func putReturnTime(allOperations []porcupine.Operation, reports []report.ClientReport, persistedRequests []model.EtcdRequest) map[keyValue]int64 {
+func uniquePutReturnTime(allOperations []porcupine.Operation, reports []report.ClientReport, persistedRequests []model.EtcdRequest, clientPutCount map[keyValue]int64) map[keyValue]int64 {
 	earliestReturnTime := map[keyValue]int64{}
 	var lastReturnTime int64
 	for _, op := range allOperations {
@@ -167,6 +167,9 @@ func putReturnTime(allOperations []porcupine.Operation, reports []report.ClientR
 					continue
 				}
 				kv := keyValue{Key: etcdOp.Put.Key, Value: etcdOp.Put.Value}
+				if count := clientPutCount[kv]; count > 1 {
+					continue
+				}
 				if returnTime, ok := earliestReturnTime[kv]; !ok || returnTime > op.Return {
 					earliestReturnTime[kv] = op.Return
 				}
@@ -192,6 +195,9 @@ func putReturnTime(allOperations []porcupine.Operation, reports []report.ClientR
 					case model.RangeOperation:
 					case model.PutOperation:
 						kv := keyValue{Key: event.Key, Value: event.Value}
+						if count := clientPutCount[kv]; count > 1 {
+							continue
+						}
 						if t, ok := earliestReturnTime[kv]; !ok || t > resp.Time.Nanoseconds() {
 							earliestReturnTime[kv] = resp.Time.Nanoseconds()
 						}
@@ -214,6 +220,9 @@ func putReturnTime(allOperations []porcupine.Operation, reports []report.ClientR
 					continue
 				}
 				kv := keyValue{Key: op.Put.Key, Value: op.Put.Value}
+				if count := clientPutCount[kv]; count > 1 {
+					continue
+				}
 				returnTime, ok := earliestReturnTime[kv]
 				if ok {
 					lastReturnTime = min(returnTime, lastReturnTime)
diff --git a/tests/robustness/validate/patch_history_test.go b/tests/robustness/validate/patch_history_test.go
index bb104b012..b5611d602 100644
--- a/tests/robustness/validate/patch_history_test.go
+++ b/tests/robustness/validate/patch_history_test.go
@@ -318,6 +318,58 @@ func TestPatchHistory(t *testing.T) {
 				{Return: infinite + 99, Output: model.MaybeEtcdResponse{Persisted: true}},
 			},
 		},
+		{
+			name: "failed put remains if there is a matching persisted request, uniqueness of this operation and following operation allows patching based on following operation",
+			historyFunc: func(h *model.AppendableHistory) {
+				h.AppendPut("key1", "value1", 300, infinite, nil, errors.New("failed"))
+				h.AppendPut("key2", "value2", 500, 600, &clientv3.PutResponse{}, nil)
+			},
+			persistedRequest: []model.EtcdRequest{
+				putRequest("key1", "value1"),
+				putRequest("key2", "value2"),
+			},
+			expectedRemainingOperations: []porcupine.Operation{
+				{Return: 599, Output: model.MaybeEtcdResponse{Persisted: true}},
+				{Return: 600, Output: putResponse(model.EtcdOperationResult{})},
+			},
+		},
+		{
+			name: "failed put remains if there is a matching persisted request, lack of uniqueness of this operation prevents patching based on following operation",
+			historyFunc: func(h *model.AppendableHistory) {
+				h.AppendPut("key1", "value1", 100, 200, &clientv3.PutResponse{}, nil)
+				h.AppendPut("key1", "value1", 300, infinite, nil, errors.New("failed"))
+				h.AppendPut("key2", "value2", 500, 600, &clientv3.PutResponse{}, nil)
+			},
+			persistedRequest: []model.EtcdRequest{
+				putRequest("key1", "value1"),
+				putRequest("key1", "value1"),
+				putRequest("key2", "value2"),
+			},
+			expectedRemainingOperations: []porcupine.Operation{
+				{Return: 200, Output: putResponse(model.EtcdOperationResult{})},
+				{Return: infinite + 600, Output: model.MaybeEtcdResponse{Error: "failed"}},
+				{Return: 600, Output: putResponse(model.EtcdOperationResult{})},
+			},
+		},
+		{
+			name: "failed put remains if there is a matching persisted request, lack of uniqueness of following operation prevents patching based on following operation",
+			historyFunc: func(h *model.AppendableHistory) {
+				h.AppendPut("key2", "value2", 100, 200, &clientv3.PutResponse{}, nil)
+				h.AppendPut("key1", "value1", 300, infinite, nil, errors.New("failed"))
+				h.AppendPut("key2", "value2", 500, 600, &clientv3.PutResponse{}, nil)
+			},
+			persistedRequest: []model.EtcdRequest{
+				putRequest("key2", "value2"),
+				putRequest("key1", "value1"),
+				putRequest("key2", "value2"),
+			},
+			expectedRemainingOperations: []porcupine.Operation{
+				{Return: 200, Output: putResponse(model.EtcdOperationResult{})},
+				// TODO: We can infer that failed operation finished before last operation matching following.
+				{Return: infinite + 598, Output: model.MaybeEtcdResponse{Persisted: true}},
+				{Return: 600, Output: putResponse(model.EtcdOperationResult{})},
+			},
+		},
 		{
 			name: "failed txn empty/delete remains",
 			historyFunc: func(h *model.AppendableHistory) {