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.BuilderView on GitHub (pinned to 01a25a7d17)
Solutions
- Read the stderr portion of the message to see the hook's own error and fix the hook script.
- Run the hook manually with the same inputs to reproduce and debug.
- Remove or fix the make_mycnf hook if custom config generation is not needed, letting the template path be used.
- 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
- Test custom hooks manually with representative inputs before rollout
- Make hook scripts executable and use explicit interpreter shebangs
- Make hooks fail loudly but deterministically; log to stderr
- Avoid hooks unless custom my.cnf generation is truly required
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
- could not initConfig in %v: %v
- no client certs for connection
- unexpected: query ended without no results and no error
- overflow
- mysqld >= 8.0.21 required to disable the redo log
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/39f421df9289dbcb.
Report an issue: GitHub.