k3s-io/k3s · error

cannot use S3 config secret when restoring snapshot; configu

Error message

cannot use S3 config secret when restoring snapshot; configuration must be set in CLI or config file

What it means

During --cluster-reset with an S3 snapshot, getS3Client returned s3.ErrNoConfigSecret: S3 credentials were configured to come from a Kubernetes secret, but at reset time no apiserver exists to read secrets from. The error mandates CLI/config-file S3 settings for restore operations.

Source

Thrown at pkg/etcd/etcd.go:395

					return false, nil
				}
			}
			return false, nil
		})
	}()

	if err := e.startClient(ctx); err != nil {
		return err
	}

	// If asked to restore from a snapshot, do so
	if e.config.ClusterResetRestorePath != "" {
		if e.config.EtcdS3 != nil {
			logrus.Infof("Retrieving etcd snapshot %s from S3", e.config.ClusterResetRestorePath)
			s3client, err := e.getS3Client(ctx)
			if err != nil {
				if errors.Is(err, s3.ErrNoConfigSecret) {
					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)

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Provide S3 credentials explicitly for the reset: --etcd-s3-access-key/--etcd-s3-secret-key (or equivalent config-file keys / env), plus bucket/endpoint/region flags, then rerun --cluster-reset.
  2. Alternatively copy the snapshot locally and restore from the file path without S3 flags.
  3. After the cluster is healthy again, the secret-based S3 config can be restored for routine snapshots.

Example fix

# before (fails: secret cannot be read during reset)
k3s server --cluster-reset --cluster-reset-restore-path=s3://bucket/snap --etcd-s3-secret-config-secret=s3cfg
# after (explicit credentials)
k3s server --cluster-reset --cluster-reset-restore-path=s3://bucket/snap \
  --etcd-s3-access-key=AKIA... --etcd-s3-secret-key=... --etcd-s3-bucket=bucket --etcd-s3-region=us-east-1
Defensive patterns

Strategy: validation

Validate before calling

// Before a reset that uses S3, assert credentials come from flags/file, not a k8s secret:
func s3ResetConfigOK(cfg Config) error {
	if cfg.ClusterResetRestorePath != "" && cfg.EtcdS3 != nil && cfg.EtcdS3.SecretConfigSecret != "" {
		if cfg.EtcdS3.AccessKey == "" || cfg.EtcdS3.SecretKey == "" {
			return errors.New("supply etcd-s3 access/secret keys via flags or file for cluster-reset")
		}
	}
	return nil
}

Try / catch

if err := e.Reset(ctx); err != nil {
	if strings.Contains(err.Error(), "cannot use S3 config secret when restoring snapshot") {
		// re-run reset with --etcd-s3-access-key/--etcd-s3-secret-key explicitly provided
	}
}

Prevention

When it happens

Trigger: EtcdS3 configured with secretConfigSecret (credentials sourced from a k8s Secret) while running k3s server --cluster-reset --cluster-reset-restore-path=s3://...; the secret-retrieval path cannot execute pre-cluster.

Common situations: Disaster-recovery runs using the same S3-secret-based config that normal (running-cluster) snapshots used; config.yaml carries etcd-s3-secret-config-secret.

Related errors


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