vitessio/vitess · error

make_mycnf hook failed(%v): %v

Error message

make_mycnf hook failed(%v): %v

What it means

The optional 'make_mycnf' hook script ran but returned an exit status other than success (and not HOOK_DOES_NOT_EXIST), so mysqld cannot generate my.cnf. The hook's exit status and stderr are surfaced in the message. This is the default branch of the hook result switch in initConfig.

Source

Thrown at go/vt/mysqlctl/mysqld.go:1463

func (mysqld *Mysqld) initConfig(cnf *Mycnf, outFile string) error {
	var err error
	var configData string

	env := make(map[string]string)
	envVars := []string{"KEYSPACE", "SHARD", "TABLET_TYPE", "TABLET_ID", "TABLET_DIR", "MYSQL_PORT"}
	for _, v := range envVars {
		env[v] = os.Getenv(v)
	}

	switch hr := hook.NewHookWithEnv("make_mycnf", nil, env).Execute(); hr.ExitStatus {
	case hook.HOOK_DOES_NOT_EXIST:
		log.Info("make_mycnf hook doesn't exist, reading template files")
		configData, err = cnf.makeMycnf(mysqld.getMycnfTemplate())
	case hook.HOOK_SUCCESS:
		configData, err = cnf.fillMycnfTemplate(hr.Stdout)
	default:
		return fmt.Errorf("make_mycnf hook failed(%v): %v", hr.ExitStatus, hr.Stderr)
	}
	if err != nil {
		return err
	}

	return os2.WriteFile(outFile, []byte(configData))
}

func (mysqld *Mysqld) getMycnfTemplate() string {
	if mycnfTemplateFile != "" {
		data, err := os.ReadFile(mycnfTemplateFile)
		if err != nil {
			log.Error(fmt.Sprintf("template file specified by -mysqlctl-mycnf-template could not be read: %v", mycnfTemplateFile))
			os.Exit(1)
		}
		return string(data) // use only specified template
	}
	var myTemplateSource strings.Builder

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Read the stderr portion of the message to see the hook's own error and fix the hook script.
  2. Run the hook manually with the same inputs to reproduce and debug.
  3. Remove or fix the make_mycnf hook if custom config generation is not needed, letting the template path be used.
  4. Verify the hook script is executable and returns hook.HOOK_SUCCESS (exit 0).

Example fix

// before (hook script)
#!/bin/sh
cat ${TEMPLATE} # TEMPLATE unset -> fails
// after
#!/bin/sh
: "${TEMPLATE:=/vthook/mycnf/template.cnf}"
cat "$TEMPLATE"
Defensive patterns

Strategy: validation

Validate before calling

hookPath := filepath.Join(vtenv.VtRoot(), "vthook", "make_mycnf")
if _, err := os.Stat(hookPath); err == nil {
    if info, _ := os.Stat(hookPath); info.Mode()&0o111 == 0 {
        return fmt.Errorf("make_mycnf hook not executable")
    }
}

Try / catch

if err := mysqld.InitConfig(cnf, outFile); err != nil {
    if strings.Contains(err.Error(), "make_mycnf hook failed") {
        log.Errorf("hook exit/stderr: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Mysqld.InitConfig / Start with a hook named 'make_mycnf' present in vtenv/vthook path, where the hook exits non-zero (neither HOOK_SUCCESS nor HOOK_DOES_NOT_EXIST).

Common situations: Custom my.cnf generation hook with a bug or missing dependency; hook script not executable / wrong interpreter; hook emits error because required env vars or template files are absent.

Related errors


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