vitessio/vitess · error

failed to execute tablet FQDN template for %+v: %w

Error message

failed to execute tablet FQDN template for %+v: %w

What it means

Thrown by parseTablet when the cluster's TabletFQDNTmpl template fails to execute against the parsed tablet. vtadmin uses this Go text/template to derive each tablet's fully qualified domain name from its fields; template execution errors (bad syntax handled at parse time aside) surface here as wrapped errors.

Source

Thrown at go/vt/vtadmin/cluster/cluster.go:349

	if topotablet.Alias.Cell != cell {
		// (TODO:@amason) ???
		log.Warn(fmt.Sprintf("tablet cell %s does not match alias %s. ignoring for now", cell, topoproto.TabletAliasString(topotablet.Alias)))
	}

	if mtstStr != "" {
		timeTime, err := time.Parse(time.RFC3339, mtstStr)
		if err != nil {
			return nil, fmt.Errorf("failed parsing primary_term_start_time %s: %w", mtstStr, err)
		}

		topotablet.PrimaryTermStartTime = protoutil.TimeToProto(timeTime)
	}

	if c.TabletFQDNTmpl != nil {
		tablet.FQDN, err = textutil.ExecuteTemplate(c.TabletFQDNTmpl, tablet)
		if err != nil {
			return nil, fmt.Errorf("failed to execute tablet FQDN template for %+v: %w", tablet, err)
		}
	}

	return tablet, nil
}

// ApplySchema applies a schema to the given keyspace in this cluster.
func (c *Cluster) ApplySchema(ctx context.Context, req *vtctldatapb.ApplySchemaRequest) (*vtctldatapb.ApplySchemaResponse, error) {
	span, ctx := trace.NewSpan(ctx, "Cluster.ApplySchema")
	defer span.Finish()

	AnnotateSpan(c, span)
	span.Annotate("keyspace", req.Keyspace)
	span.Annotate("sql", strings.Join(req.Sql, "; "))
	span.Annotate("ddl_strategy", req.DdlStrategy)
	span.Annotate("uuid_list", strings.Join(req.UuidList, ", "))
	span.Annotate("migration_context", req.MigrationContext)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the wrapped error and the printed tablet (%+v) to see which template expression failed.
  2. Verify every field referenced in TabletFQDNTmpl exists on the vtadminpb.Tablet struct for your vtadmin version.
  3. Test the template locally with text/template against a sample tablet struct before deploying.
  4. Correct the template in the vtadmin cluster config (e.g. use {{.Tablet.Alias.Cell}}-{{.Tablet.Alias.Uid}} style references matching the actual struct).

Example fix

// before (template references nonexistent field)
tabletFQDNTmpl: "{{.Hostname}}.{{.BadField}}"
// after
tabletFQDNTmpl: "{{.Tablet.Alias.Cell}}-{{.Tablet.Alias.Uid}}.example.com"
Defensive patterns

Strategy: validation

Validate before calling

tmpl, err := template.New("fqdn").Parse(cfg.TabletFQDNTmpl)
if err != nil {
	return fmt.Errorf("invalid tabletFQDNTmpl: %w", err)
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, sampleTablet); err != nil {
	return fmt.Errorf("tabletFQDNTmpl does not fit tablet struct: %w", err)
}

Type guard

func templateFits(tmplStr string, sample *vtadminpb.Tablet) bool {
	t, err := template.New("t").Parse(tmplStr)
	if err != nil {
		return false
	}
	return t.Execute(io.Discard, sample) == nil
}

Prevention

When it happens

Trigger: Calling tablet-discovery methods on a cluster configured with a TabletFQDNTmpl whose execution fails for a given tablet — e.g. the template references fields/keys not available on the tablet struct, or a custom function invoked by the template errors.

Common situations: Misconfigured vtadmin cluster.yaml `tabletFQDNTmpl` referencing wrong template variables (e.g. {{.Alias.Cell}} misspelled); template written for a different struct shape after a vtadmin version upgrade.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/e12f56976dfe605e. Report an issue: GitHub.