k3s-io/k3s · error
invalid snapshot operation
Error message
invalid snapshot operation
What it means
POST /db/snapshot dispatches on the request's Operation field, which must be one of list, save, prune, or delete (SnapshotOperation* constants). The default branch routes unknown operations to handleInvalid, which responds HTTP 400 with id etcd-snapshot.
Source
Thrown at pkg/etcd/snapshot_handler.go:139
func (e *ETCD) handleDelete(rw http.ResponseWriter, req *http.Request, snapshots []string) error {
if e.config.EtcdS3 != nil {
if _, err := e.getS3Client(req.Context()); err != nil {
err = errors.WithMessage(err, "failed to initialize S3 client")
util.SendError(err, rw, req, http.StatusBadRequest)
return nil
}
}
sr, err := e.DeleteSnapshots(req.Context(), snapshots)
if sr == nil {
util.SendError(err, rw, req, http.StatusInternalServerError)
return nil
}
sendSnapshotResponse(rw, req, sr)
return err
}
func (e *ETCD) handleInvalid(rw http.ResponseWriter, req *http.Request) error {
util.SendErrorWithID(errors.New("invalid snapshot operation"), "etcd-snapshot", rw, req, http.StatusBadRequest)
return nil
}
// withRequest returns a modified ETCD struct that is overridden
// with etcd snapshot config from the snapshot request.
func (e *ETCD) withRequest(sr *SnapshotRequest) *ETCD {
re := &ETCD{
client: e.client,
config: &config.Control{
CriticalControlArgs: e.config.CriticalControlArgs,
Runtime: e.config.Runtime,
DataDir: e.config.DataDir,
Datastore: e.config.Datastore,
DisableAgent: e.config.DisableAgent,
EtcdSnapshotCompress: e.config.EtcdSnapshotCompress,
EtcdSnapshotName: e.config.EtcdSnapshotName,
EtcdSnapshotRetention: e.config.EtcdSnapshotRetention,
EtcdS3: sr.S3,View on GitHub (pinned to 6ba341e396)
Solutions
- Use one of the supported operations exactly: list, save, prune, delete.
- Align CLI and server versions so both ends speak the same operation set.
- Inspect the outgoing JSON body and confirm the operation field is present and lowercase.
Example fix
# before
curl -X POST https://node:6443/db/snapshot -d '{"operation":"list-all"}'
# after
curl -X POST https://node:6443/db/snapshot -d '{"operation":"list"}' Defensive patterns
Strategy: validation
Validate before calling
var validOps = map[string]bool{"list": true, "save": true, "prune": true, "delete": true}
if !validOps[sr.Operation] {
return fmt.Errorf("invalid snapshot operation %q (want list|save|prune|delete)", sr.Operation)
} Type guard
func isValidSnapshotOperation(op string) bool {
switch op {
case "list", "save", "prune", "delete":
return true
}
return false
} Prevention
- Pin CLI and server versions together in automation.
- Unit-test JSON request builders against the server's operation constants.
When it happens
Trigger: Sending a SnapshotRequest whose operation is misspelled (e.g. 'List', 'lists', 'delete-snapshot') or using an operation added in a newer server than the CLI in use; hand-rolled HTTP clients omitting the operation field.
Common situations: Version skew between k3s CLI and server where operation names changed; curl scripts with typos; JSON payloads built by templating that drops the field.
Related errors
- no snapshots given for removal
- invalid output format:
- etcd-snapshot-reconcile-interval must be greater than 0s
- token must not be empty
- unknown stage %s requested
AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15).
Data as JSON: /api/errors/7e473bfaf4353294.
Report an issue: GitHub.