cluster-reset-restore-path doubles the snapshot path for compressed (.zip) snapshots
Environmental Info: K3s Version: v1.36.3+k3s1 (also reproduced on v1.35.5+k3s1; v1.35.2+k3s1 is NOT affected)
Node(s) CPU architecture, OS, and Version: x86_64, Debian 13 (6.12 kernel)
Cluster Configuration: 1 server, restoring etcd from a compressed snapshot
Describe the bug:
Restoring a compressed (.zip) etcd snapshot with the documented full path in --cluster-reset-restore-path fails, because decompression joins the snapshot dir onto a path that is already absolute, producing a doubled path.
Steps To Reproduce:
- Installed K3s: downloaded the release binary for each version onto a throwaway VM
k3s server --cluster-init ..., thenk3s etcd-snapshot save --name repro --snapshot-compresssystemctl stop k3s(or kill the server)- Restore with the documented full path:
k3s server --cluster-reset --cluster-reset-restore-path=/var/lib/rancher/k3s/server/db/snapshots/repro.zip
Expected behavior:
The full path to a compressed snapshot restores, the same as an uncompressed one, per https://docs.k3s.io/cli/etcd-snapshot.
Actual behavior:
On v1.36.3+k3s1 and v1.35.5+k3s1:
level=info msg="Decompressing etcd snapshot file: /var/lib/rancher/k3s/server/db/snapshots/repro.zip" level=fatal msg="Error: starting kubernetes: failed to start cluster: start managed database: open /var/lib/rancher/k3s/server/db/snapshots/var/lib/rancher/k3s/server/db/snapshots/repro.zip: no such file or directory"
The snapshot dir is prepended twice. Same snapshot and same command on v1.35.2+k3s1 work fine (proceeds to "restoring snapshot"). Passing a bare filename instead fails earlier with snapshot path does not exist, so there's no working invocation for a compressed snapshot on the affected versions.
Additional context / logs:
This looks like it started with #13826 (commit 4cc440f2c930, "Simplify snapshot compress/decompress logic"), backported via #13827 / #13828 / #13829 / #13830.
decompressSnapshot in pkg/etcd/snapshot.go now does:
snapshotPath := filepath.Join(snapshotDir, snapshotFilename)but the caller ETCD.Restore in pkg/etcd/etcd.go still passes the full ClusterResetRestorePath as the filename argument, so the dir gets prepended a second time. The uncompressed branch uses the path as-is, which is why only .zip snapshots are affected. S3 snapshots are affected too, since k3s sets ClusterResetRestorePath to the local full path after download and then decompresses.
Affected code paths I could see: 1.36.x (all), 1.35.3+, 1.34.7+, and master. 1.35.2 and earlier work. A fix would either strip the dir before the join, or have the caller pass only the basename.
Source: k3s-io/k3s