{"record":{"id":"97a96479d5887ef5","repo":"vitessio/vitess","slug":"failed-to-execute-vtgate-address-template-for-v","errorCode":null,"errorMessage":"failed to execute vtgate address template for %v: %w","messagePattern":"failed to execute vtgate address template for (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtadmin/cluster/discovery/discovery_consul.go","lineNumber":224,"sourceCode":"\n\treturn vtgates[rand.IntN(len(vtgates))], nil\n}\n\n// DiscoverVTGateAddr is part of the Discovery interface.\nfunc (c *ConsulDiscovery) DiscoverVTGateAddr(ctx context.Context, tags []string) (string, error) {\n\tspan, ctx := trace.NewSpan(ctx, \"ConsulDiscovery.DiscoverVTGateAddr\")\n\tdefer span.Finish()\n\n\texecuteFQDNTemplate := false\n\n\tvtgate, err := c.discoverVTGate(ctx, tags, executeFQDNTemplate)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\taddr, err := textutil.ExecuteTemplate(c.vtgateAddrTmpl, vtgate)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to execute vtgate address template for %v: %w\", vtgate, err)\n\t}\n\n\treturn addr, nil\n}\n\n// DiscoverVTGateAddrs is part of the Discovery interface.\nfunc (c *ConsulDiscovery) DiscoverVTGateAddrs(ctx context.Context, tags []string) ([]string, error) {\n\tspan, ctx := trace.NewSpan(ctx, \"ConsulDiscovery.DiscoverVTGateAddrs\")\n\tdefer span.Finish()\n\n\texecuteFQDNTemplate := false\n\n\tvtgates, err := c.discoverVTGates(ctx, tags, executeFQDNTemplate)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\taddrs := make([]string, len(vtgates))","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtadmin/cluster/discovery/discovery_consul.go#L206-L242","documentation":"This error is returned by Cluster.DiscoverVTGateAddr when the configured Go text template for rendering a single vtgate's address (c.vtgateAddrTmpl) fails to execute against the discovered vtgate protobuf. textutil.ExecuteTemplate wraps template.Template.Execute, so the underlying error is a text/template execution error (e.g. the template references a field that does not exist on vtadminpb.VTGate). The error is wrapped with %w so the root cause can be inspected with errors.Is/As.","triggerScenarios":"Calling DiscoverVTGateAddr on a consul-backed discovery cluster whose vtgate_addr_template option contains field references that do not match vtadminpb.VTGate (e.g. {{.Port}} when the proto only exposes PortStr) or has invalid template actions that fail at execution time.","commonSituations":"Operators set a custom vtgate-addr-template in the vtadmin cluster config copied from docs for a different proto version; renaming fields in the VTGate proto breaks an old template; typos like {{.Hostname}} vs {{.Host}}.","solutions":["Fix the vtgate address template in the cluster config so every {{...}} action matches an exported field of vtadminpb.VTGate","Test the template locally against a sample VTGate struct with text/template before deploying","If a recent Vitess upgrade introduced this, check the release notes for VTGate proto field renames and update the template"],"exampleFix":"// before (config)\nvtgate_addr_template: \"{{.HostName}}:{{.Port}}\"\n// after (fields matching vtadminpb.VTGate)\nvtgate_addr_template: \"{{.Hostname}}:{{.PortStr}}\"","handlingStrategy":"validation","validationCode":"// validate the template before wiring it into the cluster\nvtgateTmpl := template.Must(template.New(\"vtgate-addr\").Parse(cfg.VtgateAddrTmpl))\nvar sample vtadminpb.VTGate\nif err := vtgateTmpl.Execute(io.Discard, &sample); err != nil {\n\treturn fmt.Errorf(\"invalid vtgate address template: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"addr, err := cluster.DiscoverVTGateAddr(ctx)\nif err != nil {\n\tvar tErr *template.ExecError // or use errors.As on wrapped cause\n\tif errors.As(err, &tErr) {\n\t\tlog.Errorf(\"bad vtgate addr template: %v\", err)\n\t\treturn fallbackAddr\n\t}\n\treturn err\n}","preventionTips":["Keep templates referencing only documented vtadminpb.VTGate fields","Compile templates with template.Must at process startup to fail fast","After upgrading Vitess, diff the VTGate proto against your templates","Add a config unit test that executes all configured templates against fixture protos"],"tags":["go","vtadmin","consul","template"],"backgroundTag":"template-execution-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}