{"record":{"id":"a95011f31b0f20e5","repo":"vitessio/vitess","slug":"mapping-row-to-keyspace-id-returned-an-invalid-arr","errorCode":null,"errorMessage":"mapping row to keyspace id returned an invalid array of destinations: %v","messagePattern":"mapping row to keyspace id returned an invalid array of destinations: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/binlog/keyspace_id_resolver.go","lineNumber":110,"sourceCode":"\t\t\t}\n\t\t}\n\t\t// The column was not found.\n\t\treturn -1, nil, fmt.Errorf(\"cannot find column %v in table %v\", shardingColumnName, table.Name)\n\t}, nil\n}\n\n// keyspaceIDResolverFactoryV3 uses the Vindex to compute the value.\ntype keyspaceIDResolverFactoryV3 struct {\n\tvindex vindexes.SingleColumn\n}\n\nfunc (r *keyspaceIDResolverFactoryV3) keyspaceID(v sqltypes.Value) ([]byte, error) {\n\tdestinations, err := r.vindex.Map(context.TODO(), nil, []sqltypes.Value{v})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(destinations) != 1 {\n\t\treturn nil, fmt.Errorf(\"mapping row to keyspace id returned an invalid array of destinations: %v\", key.DestinationsString(destinations))\n\t}\n\tksid, ok := destinations[0].(key.DestinationKeyspaceID)\n\tif !ok || len(ksid) == 0 {\n\t\treturn nil, fmt.Errorf(\"could not map %v to a keyspace id, got destination %v\", v, destinations[0])\n\t}\n\treturn ksid, nil\n}\n","sourceCodeStart":92,"sourceCodeEnd":118,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/binlog/keyspace_id_resolver.go#L92-L118","documentation":"After mapping the sharding-key value through the vindex, the resolver expects exactly one destination. Any other count (zero, multiple, or scatter) is invalid for keyspace-id computation during binlog streaming.","triggerScenarios":"keyspaceID(v) called with a vindex whose Map() returns a destinations slice with len != 1 (e.g. lookup vindex returning empty, or a vindex mapping to multiple shards).","commonSituations":"Using a non-unique or lookup vindex that returns no/many destinations for a row's sharding key during keyrange streaming; data inconsistency in a lookup vindex table.","solutions":["Use a unique vindex (hash, consistent_lookup_unique) as the sharding vindex for streamed tables.","Fix the lookup vindex table contents so the key maps to exactly one destination.","Check the printed destinations string to see how many/which destinations were returned and why."],"exampleFix":"// before (non-unique lookup vindex)\n{\"vindexes\":{\"lk\":{\"type\":\"lookup_hash_unique\"...}}\n// after\n{\"vindexes\":{\"lk\":{\"type\":\"consistent_lookup_unique\"...}}","handlingStrategy":"type-guard","validationCode":"// ensure the sharding vindex is unique/functional before streaming\nvdef := vschema.Vindexes[vindexName]\nif !isUniqueVindexType(vdef.Type) {\n\treturn fmt.Errorf(\"vindex %s must be unique for keyrange streaming\", vindexName)\n}","typeGuard":"func isSingleKeyspaceID(dest key.Destination) bool {\n\t_, ok := dest.(key.DestinationKeyspaceID)\n\treturn ok\n}","tryCatchPattern":"if err := streamKeyRange(ctx, kr); err != nil {\n\tif strings.Contains(err.Error(), \"invalid array of destinations\") {\n\t\t// switch to a unique vindex or repair lookup table\n\t}\n\treturn err\n}","preventionTips":["Use unique functional vindexes (hash, binary, unique lookup) as sharding vindexes.","Periodically verify lookup vindex tables have exactly one row per key.","Log destination strings when mapping anomalies appear in backups/streams."],"tags":["vindex","keyspace-id","binlog","mapping"],"backgroundTag":"vindex-destination-invalid","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}