vitessio/vitess · error

BaseKeyspace is required for SNAPSHOT keyspaces

Error message

BaseKeyspace is required for SNAPSHOT keyspaces

What it means

CreateKeyspace validates that SNAPSHOT-type keyspaces carry a BaseKeyspace identifying the keyspace they were snapshotted from. Since a SNAPSHOT keyspace is a point-in-time copy of another keyspace, omitting the source keyspace leaves the snapshot unanchored and unusable, so the request is rejected before any topology mutation occurs.

Source

Thrown at go/vt/vtctl/grpcvtctldserver/server.go:933

// CreateKeyspace is part of the vtctlservicepb.VtctldServer interface.
func (s *VtctldServer) CreateKeyspace(ctx context.Context, req *vtctldatapb.CreateKeyspaceRequest) (resp *vtctldatapb.CreateKeyspaceResponse, err error) {
	span, ctx := trace.NewSpan(ctx, "VtctldServer.CreateKeyspace")
	defer span.Finish()

	defer panicHandler(&err)

	span.Annotate("keyspace", req.Name)
	span.Annotate("keyspace_type", topoproto.KeyspaceTypeLString(req.Type))
	span.Annotate("force", req.Force)
	span.Annotate("allow_empty_vschema", req.AllowEmptyVSchema)
	span.Annotate("durability_policy", req.DurabilityPolicy)

	switch req.Type {
	case topodatapb.KeyspaceType_NORMAL:
	case topodatapb.KeyspaceType_SNAPSHOT:
		if req.BaseKeyspace == "" {
			err = errors.New("BaseKeyspace is required for SNAPSHOT keyspaces")
			return nil, err
		}

		if req.SnapshotTime == nil {
			err = errors.New("SnapshotTime is required for SNAPSHOT keyspaces")
			return nil, err
		}

		span.Annotate("base_keyspace", req.BaseKeyspace)
		span.Annotate("snapshot_time", protoutil.TimeFromProto(req.SnapshotTime).String())
	default:
		return nil, fmt.Errorf("unknown keyspace type %v", req.Type)
	}

	ki := &topodatapb.Keyspace{
		KeyspaceType:     req.Type,
		BaseKeyspace:     req.BaseKeyspace,
		SnapshotTime:     req.SnapshotTime,

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Pass --base-keyspace <source-keyspace> (or set req.BaseKeyspace) when creating a SNAPSHOT keyspace
  2. If a full independent keyspace is intended, omit --type so the keyspace is created as NORMAL
  3. Set req.SnapshotTime as well, since it is validated immediately after BaseKeyspace

Example fix

// before
req := &vtctldatapb.CreateKeyspaceRequest{Type: topodatapb.KeyspaceType_SNAPSHOT}
// after
req := &vtctldatapb.CreateKeyspaceRequest{
  Type: topodatapb.KeyspaceType_SNAPSHOT,
  BaseKeyspace: "commerce",
  SnapshotTime: timestamppb.New(snapshotTime),
}
Defensive patterns

Strategy: validation

Validate before calling

if req.GetType() == topodatapb.KeyspaceType_SNAPSHOT && req.GetBaseKeyspace() == "" {
    return fmt.Errorf("BaseKeyspace must be set for SNAPSHOT keyspace %s", req.Name)
}

Prevention

When it happens

Trigger: Calling vtctldclient CreateKeyspace (or the grpcvtctldserver CreateKeyspace RPC) with req.Type set to topodatapb.KeyspaceType_SNAPSHOT while req.BaseKeyspace is an empty string.

Common situations: CLI invocations that set --type=SNAPSHOT but forget --base-keyspace; programmatic keyspace creation scripts copying templates from NORMAL keyspaces; vitess-operator or plan reconcilers emitting partial Keyspace protos.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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