vitessio/vitess · error

unknown keyspace type %v

Error message

unknown keyspace type %v

What it means

CreateKeyspace validates that req.Type is one of the supported KeyspaceType values (NORMAL or SNAPSHOT). Any other protobuf enum value falls into the switch's default branch and is rejected with this fmt.Errorf before any topology writes occur.

Source

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

	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,
		DurabilityPolicy: req.DurabilityPolicy,
		SidecarDbName:    req.SidecarDbName,
	}

	err = s.ts.CreateKeyspace(ctx, req.Name, ki)
	if req.Force && topo.IsErrType(err, topo.NodeExists) {
		log.Info(fmt.Sprintf("keyspace %v already exists (ignoring error with Force=true)", req.Name))
		err = nil

		// Get the actual keyspace out of the topo; it may differ in structure,
		// and we want to return the authoritative version as the "created" one
		// to the client.

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Set req.Type to topodatapb.KeyspaceType_NORMAL (the default for ordinary keyspaces)
  2. Only use topodatapb.KeyspaceType_SNAPSHOT when creating snapshot keyspaces with BaseKeyspace and SnapshotTime set
  3. Ensure the client library and server use the same vitess proto version

Example fix

// before
req.Type = topodatapb.KeyspaceType(7)
// after
req.Type = topodatapb.KeyspaceType_NORMAL
Defensive patterns

Strategy: validation

Validate before calling

if req.Type != topodatapb.KeyspaceType_NORMAL && req.Type != topodatapb.KeyspaceType_SNAPSHOT {
    return fmt.Errorf("unsupported keyspace type %v", req.Type)
}

Type guard

func validKeyspaceType(t topodatapb.KeyspaceType) bool {
    return t == topodatapb.KeyspaceType_NORMAL || t == topodatapb.KeyspaceType_SNAPSHOT
}

Try / catch

_, err := client.CreateKeyspace(ctx, req)
if err != nil && strings.Contains(err.Error(), "unknown keyspace type") {
    req.Type = topodatapb.KeyspaceType_NORMAL // retry with default
}

Prevention

When it happens

Trigger: Calling CreateKeyspace with req.Type set to an invalid/undefined topodatapb.KeyspaceType value (including the zero value if it is not handled, or a corrupt/garbage enum from a hand-built request).

Common situations: Hand-crafted RPC requests or generated clients using wrong enum values; copy-paste from code constructing a SNAPSHOT keyspace; protobuf enum deserialization from an incompatible client version.

Related errors


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