{"record":{"id":"b69745b480dea5d3","repo":"vitessio/vitess","slug":"failed-to-parse-vtgate-host-address-template-s","errorCode":null,"errorMessage":"failed to parse vtgate host address template %s: %w","messagePattern":"failed to parse vtgate host address template (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtadmin/cluster/discovery/discovery_consul.go","lineNumber":141,"sourceCode":"\n\t/* gates options */\n\tif *vtgateDatacenterTmplStr != \"\" {\n\t\tdisco.vtgateDatacenter, err = generateConsulDatacenter(\"vtgate\", cluster, *vtgateDatacenterTmplStr)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to generate vtgate consul datacenter from template: %w\", err)\n\t\t}\n\t}\n\n\tif *vtgateFQDNTmplStr != \"\" {\n\t\tdisco.vtgateFQDNTmpl, err = template.New(\"consul-vtgate-fqdn-template-\" + cluster.Id).Parse(*vtgateFQDNTmplStr)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse vtgate FQDN template %s: %w\", *vtgateFQDNTmplStr, err)\n\t\t}\n\t}\n\n\tdisco.vtgateAddrTmpl, err = template.New(\"consul-vtgate-address-template-\" + cluster.Id).Parse(*vtgateAddrTmplStr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse vtgate host address template %s: %w\", *vtgateAddrTmplStr, err)\n\t}\n\n\t/* vtctld options */\n\tif *vtctldDatacenterTmplStr != \"\" {\n\t\tdisco.vtctldDatacenter, err = generateConsulDatacenter(\"vtctld\", cluster, *vtctldDatacenterTmplStr)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to generate vtctld consul datacenter from template: %w\", err)\n\t\t}\n\t}\n\n\tif *vtctldFQDNTmplStr != \"\" {\n\t\tdisco.vtctldFQDNTmpl, err = template.New(\"consul-vtctld-fqdn-template-\" + cluster.Id).Parse(*vtctldFQDNTmplStr)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse vtctld FQDN template %s: %w\", *vtctldFQDNTmplStr, err)\n\t\t}\n\t}\n\n\tdisco.vtctldAddrTmpl, err = template.New(\"consul-vtctld-address-template-\" + cluster.Id).Parse(*vtctldAddrTmplStr)","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtadmin/cluster/discovery/discovery_consul.go#L123-L159","documentation":"NewConsul always parses the vtgate address template (unlike the datacenter/FQDN options, there is no empty-string skip). If template.Parse fails, this error wraps the raw string and parse error. It means the vtgate address template cannot be compiled into a Go text/template.","triggerScenarios":"Calling NewConsul with a vtgate address template flag value containing invalid Go template syntax or unknown functions; this occurs unconditionally on every consul discovery construction, even if the address would not otherwise be used.","commonSituations":"Missing closing braces, shell expansion eating $ or { } in env var values, using a field not defined on vtadminpb.Cluster, single-vs-double quoting mistakes in YAML.","solutions":["Correct the vtgate address template so it parses as a valid Go text/template (e.g. \"{{ .Cluster.Id }}.vtgate.example.com:15001\").","Use only fields present on vtadminpb.Cluster in the template body.","Check the wrapped parse error for the exact character offset of the syntax problem.","If config comes from env vars, verify the shell/YAML is not consuming braces or $ characters."],"exampleFix":"// before\nvtgate_address_template: \"{{ .Cluster.Id }}:{ port\" \n// after\nvtgate_address_template: \"{{ .Cluster.Id }}.vtgate:15001\"","handlingStrategy":"validation","validationCode":"if _, err := template.New(\"check\").Parse(*vtgateAddrTmplStr); err != nil {\n    return fmt.Errorf(\"invalid vtgate address template: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"disco, err := NewConsul(cluster, args)\nif err != nil && strings.Contains(err.Error(), \"vtgate host address template\") {\n    log.Fatalf(\"fix vtgate address template: %v\", err)\n}","preventionTips":["Remember the address template is parsed unconditionally — always supply a valid value.","Keep vtgate/vtctld templates in versioned config with parse tests.","Beware YAML single-quote vs double-quote differences when embedding braces."],"tags":["go","template","consul","address","config"],"backgroundTag":"template-parse-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}