vitessio/vitess · error

SaveVSchema(%v) failed: %v

Error message

SaveVSchema(%v) failed: %v

What it means

CreateKs persists the loaded keyspace VSchema to the topo server via ts.SaveVSchema. This error means the vschema was valid but writing it to topology storage failed — a topo server connectivity/permission/consistency problem, not a vschema problem.

Source

Thrown at go/vt/vtcombo/tablet_map.go:418

	if schemaDir != "" {
		f := path.Join(schemaDir, keyspace, "vschema.json")
		if _, err := os.Stat(f); err == nil {
			// load the vschema
			formal, err := vindexes.LoadFormalKeyspace(f)
			if err != nil {
				return 0, fmt.Errorf("cannot load vschema file %v for keyspace %v: %v", f, keyspace, err)
			}

			_, err = vindexes.BuildKeyspace(formal, wr.SQLParser())
			if err != nil {
				return 0, fmt.Errorf("BuildKeyspace(%v) failed: %v", keyspace, err)
			}
			ksvs := &topo.KeyspaceVSchemaInfo{
				Name:     keyspace,
				Keyspace: formal,
			}
			if err := ts.SaveVSchema(ctx, ksvs); err != nil {
				return 0, fmt.Errorf("SaveVSchema(%v) failed: %v", keyspace, err)
			}
		} else {
			log.Info(fmt.Sprintf("File %v doesn't exist, skipping vschema for keyspace %v", f, keyspace))
		}
	}

	// Rebuild the SrvKeyspace object, so we can support
	// range-based sharding queries, and export the redirects.
	if err := topotools.RebuildKeyspace(ctx, wr.Logger(), wr.TopoServer(), keyspace, nil, false); err != nil {
		return 0, fmt.Errorf("cannot rebuild %v: %v", keyspace, err)
	}
	return uid, nil
}

//
// TabletConn implementation
//

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check topo server health (etcdctl/zkCli connectivity) and vtcombo's -topo_* flags.
  2. Inspect the wrapped error for topo timeouts vs permissions.
  3. Re-run CreateKs / restart vtcombo once topo is reachable — saving vschema is idempotent.
  4. Verify the keyspace record exists in topo and there are no conflicting writers.

Example fix

// before
vtcombo -topo_implementation=etcd2 -topo_server_addr=badhost:2379 ...
// after
vtcombo -topo_implementation=etcd2 -topo_server_addr=127.0.0.1:2379 ...
Defensive patterns

Strategy: retry

Validate before calling

// verify topo reachability before CreateKs
ts, err := topo.OpenServer(topoImpl, serverAddr, root)
if err != nil {
	return fmt.Errorf("topo unavailable: %w", err)
}
if _, err := ts.GetKeyspace(ctx, keyspace); err != nil && !topo.IsErrType(err, topodata.KeyspaceId) && !topo.IsNotFound(err) {
	return fmt.Errorf("topo not usable: %w", err)
}

Try / catch

err := CreateKs(...)
if err != nil && strings.Contains(err.Error(), "SaveVSchema") {
	// topo write failed; wait for topo and retry — SaveVSchema is idempotent
	backoff.Retry(ctx, func() error { return CreateKs(...) })
}

Prevention

When it happens

Trigger: CreateKs when the topo server (etcd/zk/consul/file backend) is unreachable, the session times out, the topo connection credentials are wrong, or the keyspace record was concurrently deleted/locked.

Common situations: etcd/zookeeper down or misconfigured in local-vt combo setups; topo server request timeouts under load; topo data manually wiped while vtcombo is initializing; network partition to remote topo.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/aa558f560d53f30a. Report an issue: GitHub.