{"record":{"id":"edc70db50d06b637","repo":"vitessio/vitess","slug":"failed-to-open-external-topo-v","errorCode":null,"errorMessage":"failed to open external topo: %v","messagePattern":"failed to open external topo: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/workflow/materializer.go","lineNumber":553,"sourceCode":"\t}\n\tif len(specifiedTargetShards) > 0 {\n\t\tvar targetShards2 []*topo.ShardInfo\n\t\tfor _, shard := range targetShards {\n\t\t\tif slices.Contains(specifiedTargetShards, shard.ShardName()) {\n\t\t\t\ttargetShards2 = append(targetShards2, shard)\n\t\t\t}\n\t\t}\n\t\ttargetShards = targetShards2\n\t}\n\tif len(targetShards) == 0 {\n\t\treturn fmt.Errorf(\"no target shards specified for workflow %s \", ms.Workflow)\n\t}\n\n\tsourceTs := mz.ts\n\tif ms.ExternalCluster != \"\" { // when the source is an external mysql cluster mounted using the Mount command\n\t\texternalTopo, err := mz.ts.OpenExternalVitessClusterServer(ctx, ms.ExternalCluster)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to open external topo: %v\", err)\n\t\t}\n\t\tsourceTs = externalTopo\n\t}\n\tdifferentPVs := false\n\tsourceVSchema, err := sourceTs.GetVSchema(ctx, ms.SourceKeyspace)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get source keyspace vschema: %v\", err)\n\t}\n\tdifferentPVs = primaryVindexesDiffer(ms, sourceVSchema.Keyspace, vschema.Keyspace)\n\n\tmz.targetVSchema = targetVSchema\n\tmz.sourceShards = sourceShards\n\tmz.targetShards = targetShards\n\tmz.isPartial = isPartial\n\tmz.primaryVindexesDiffer = differentPVs\n\treturn nil\n}\n","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/workflow/materializer.go#L535-L571","documentation":"When ms.ExternalCluster is set, the source lives on an externally mounted MySQL/Vitess cluster and buildMaterializer must open that cluster's topo server via OpenExternalVitessClusterServer. This error wraps any failure opening the external topo server, making the source topology unreachable.","triggerScenarios":"Workflow creation (createWorkflowStreams / WorkflowAddTables) with --external-cluster set while the external cluster name is wrong, the mount is stale, or the external topo server is unreachable.","commonSituations":"Cluster unmounted (or name typo) before workflow creation; network/firewall blocking the external topo; external topo credentials changed; stale mount after the external cluster was re-created.","solutions":["Run `vtctl Mount` (or re-mount) the external cluster and confirm the name matches ms.ExternalCluster","Verify connectivity to the external topo server (host, port, credentials)","List mounts with `vtctl ListMounts` to confirm the cluster exists"],"exampleFix":"// before\nMoveTables --external-cluster=prod_ext_x --source-keyspace=ks\n// after\nvtctl Mount --topo-type=etcd2 --topo-server=host:2379 ext0\nMoveTables --external-cluster=ext0 --source-keyspace=ks","handlingStrategy":"validation","validationCode":"mounts, err := ts.ListMounts(ctx)\nif err != nil { return err }\nif !containsMount(mounts, externalCluster) {\n    return fmt.Errorf(\"mount %q not found; run Mount first\", externalCluster)\n}","typeGuard":null,"tryCatchPattern":"if err := createWorkflow(ctx, req); err != nil {\n    if strings.Contains(err.Error(), \"failed to open external topo\") {\n        // check ListMounts, connectivity, and re-Mount the cluster\n    }\n    return err\n}","preventionTips":["Run `vtctl ListMounts` to confirm the external cluster name before workflows","Monitor connectivity to external topo servers from the vtctld host","Re-mount external clusters after they are rebuilt or credentials rotate"],"tags":["vitess","workflow","topology","external-cluster","network"],"backgroundTag":"external-topo-unreachable","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}