vitessio/vitess · critical
failed to parse tablet fqdn template %s: %w
Error message
failed to parse tablet fqdn template %s: %w
What it means
cluster.New fails when the optional --tablet-fqdn-template value cannot be parsed as a Go text/template for the cluster. This is a pure config-syntax error: the template string (e.g. used to render tablet FQDNs) is invalid template syntax or references bad actions.
Source
Thrown at go/vt/vtadmin/cluster/cluster.go:153
for _, opt := range cfg.vtctldConfigOpts {
vtctldCfg = opt(vtctldCfg)
}
cluster.DB, err = vtsql.New(ctx, vtsqlCfg)
if err != nil {
return nil, fmt.Errorf("error creating vtsql proxy: %w", err)
}
cluster.Vtctld, err = vtctldclient.New(ctx, vtctldCfg)
if err != nil {
return nil, fmt.Errorf("error creating vtctldclient: %w", err)
}
if cfg.TabletFQDNTmplStr != "" {
cluster.TabletFQDNTmpl, err = template.New(cluster.ID + "-tablet-fqdn").Parse(cfg.TabletFQDNTmplStr)
if err != nil {
return nil, fmt.Errorf("failed to parse tablet fqdn template %s: %w", cfg.TabletFQDNTmplStr, err)
}
}
cluster.backupReadPool = cfg.BackupReadPoolConfig.NewReadPool()
cluster.schemaReadPool = cfg.SchemaReadPoolConfig.NewReadPool()
cluster.topoRWPool = cfg.TopoRWPoolConfig.NewRWPool()
cluster.topoReadPool = cfg.TopoReadPoolConfig.NewReadPool()
cluster.workflowReadPool = cfg.WorkflowReadPoolConfig.NewReadPool()
cluster.emergencyFailoverPool = cfg.EmergencyFailoverPoolConfig.NewRWPool()
cluster.failoverPool = cfg.FailoverPoolConfig.NewRWPool()
if cluster.cfg.SchemaCacheConfig == nil {
cluster.cfg.SchemaCacheConfig = &cache.Config{}
}
cluster.schemaCache = cache.New(func(ctx context.Context, key schemacache.Key) ([]*vtadminpb.Schema, error) {
// TODO: make a private method to separate the fetching bits from the cache bits
if key.Keyspace == "" {View on GitHub (pinned to 01a25a7d17)
Solutions
- Fix the template syntax in --tablet-fqdn-template (valid Go text/template, e.g. '{{.Tablet.Alias}}.{{.Cell}}.example.com')
- Validate the template with a small Go snippet or text/template playground before deploying
- Remove the flag if templating is not needed
Example fix
// before
--tablet-fqdn-template '{{.Alias'
// after
--tablet-fqdn-template '{{.Tablet.Alias}}.{{.Cell}}.ks.example.com' Defensive patterns
Strategy: validation
Validate before calling
// validate template before passing to config
if cfg.TabletFQDNTmplStr != "" {
if _, err := texttemplate.New("check").Parse(cfg.TabletFQDNTmplStr); err != nil {
return fmt.Errorf("invalid --tablet-fqdn-template: %w", err)
}
} Try / catch
c, err := cluster.BuildCluster(ctx, cfg)
if err != nil {
if strings.Contains(err.Error(), "tablet fqdn template") {
return fmt.Errorf("bad --tablet-fqdn-template %q: %w", cfg.TabletFQDNTmplStr, err)
}
return err
} Prevention
- Lint templates in CI with text/template before deploy
- Keep a known-good template snippet in deployment docs
- Test rendering the template against a sample tablet struct
When it happens
Trigger: cfg.TabletFQDNTmplStr is non-empty and template.New(...).Parse fails — e.g. unbalanced {{ }}, unknown template functions.
Common situations: Typo in the template such as '{{.Alias}}' vs '{{ .Alias }}' mistakes like '{{.Alias'; copy-paste artifacts; using unsupported fields/functions.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- error creating discovery impl (%s): %w
- error creating vtsql connection config: %w
- error creating vtctldclient proxy config: %w
- --s3-backup-storage-bucket required
- direct DDL is disabled
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/252973461eb8ad82.
Report an issue: GitHub.