k3s-io/k3s · critical

etcd: snapshot path does not exist: %s

Error message

etcd: snapshot path does not exist: %s

What it means

During cluster reset with --cluster-reset-restore-path, after an optional S3 download, k3s stats the snapshot path and requires an existing regular file. os.Stat returning IsNotExist produces this error - the configured snapshot path is not present on this node (a failed S3 download would already have failed earlier with 'failed to download snapshot from S3').

Source

Thrown at pkg/etcd/etcd.go:413

					return errors.New("cannot use S3 config secret when restoring snapshot; configuration must be set in CLI or config file")
				}
				return errors.WithMessage(err, "failed to initialize S3 client")
			}
			dir, err := snapshotDir(e.config, true)
			if err != nil {
				return errors.WithMessage(err, "failed to get the snapshot dir")
			}
			path, err := s3client.Download(ctx, e.config.ClusterResetRestorePath, dir)
			if err != nil {
				return errors.WithMessage(err, "failed to download snapshot from S3")
			}
			e.config.ClusterResetRestorePath = path
			logrus.Infof("S3 download complete for %s", e.config.ClusterResetRestorePath)
		}

		info, err := os.Stat(e.config.ClusterResetRestorePath)
		if os.IsNotExist(err) {
			return fmt.Errorf("etcd: snapshot path does not exist: %s", e.config.ClusterResetRestorePath)
		}
		if info.IsDir() {
			return fmt.Errorf("etcd: snapshot path must be a file, not a directory: %s", e.config.ClusterResetRestorePath)
		}
		if err := e.Restore(ctx); err != nil {
			return err
		}
	}

	if err := e.setName(true); err != nil {
		return err
	}
	// touch a file to avoid multiple resets
	if err := os.WriteFile(e.ResetFile(), []byte{}, 0600); err != nil {
		return err
	}

	return e.newCluster(ctx, wg, true)

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Verify the file exists on this node with an absolute path: `ls -l /var/lib/rancher/k3s/server/db/snapnapshots/` (default snapshot dir: /var/lib/rancher/k3s/server/db/snapshots) and use the full file path.
  2. If restoring on a different node, copy the snapshot file there first (or configure S3 so it is downloaded automatically).
  3. List available snapshots with `k3s etcd-snapshot ls` and re-run using the exact on-demand path or name.

Example fix

# before
k3s server \
  --cluster-reset \
  --cluster-reset-restore-path=/var/lib/rancher/k3s/server/db/snapshots

# after (point at the snapshot FILE, not a made-up path)
k3s server \
  --cluster-reset \
  --cluster-reset-restore-path=/var/lib/rancher/k3s/server/db/snapshots/etcd-snapshot-1723680000-0.db
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check the snapshot path before invoking cluster-reset restore:
info, err := os.Stat(snapshotPath)
if os.IsNotExist(err) {
    log.Fatalf("snapshot %s does not exist on this node - copy it here or check the S3 config", snapshotPath)
}
if err != nil { log.Fatal(err) }
if info.IsDir() { log.Fatalf("%s is a directory; pass the .db snapshot file", snapshotPath) }

Prevention

When it happens

Trigger: Running `k3s server --cluster-reset --cluster-reset-restore-path=/path/snapshot.db` where the path is misspelled, on a different node than where the file lives, or the file was deleted/moved (pkg/etcd/etcd.go:411-414).

Common situations: Restoring on a new node from a snapshot copied to a different location; relative path resolved against k3s's working dir; snapshot pruned by retention; scp of the snapshot never completed.

Related errors


AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15). Data as JSON: /api/errors/99371fba2bbfee76. Report an issue: GitHub.