vitessio/vitess · error

%v hook failed(%v): %v

Error message

%v hook failed(%v): %v

What it means

ExecuteOptional runs a hook and treats HOOK_DOES_NOT_EXIST / HOOK_VTROOT_ERROR / HOOK_SUCCESS as non-errors (hooks are optional), but any other exit status is returned as an error naming the hook, its exit status, and stderr. It means the hook script was found and executed but failed — its own stderr is embedded in the message.

Source

Thrown at go/vt/hook/hook.go:211

// Execute tries to execute the Hook and returns a HookResult.
func (hook *Hook) Execute() (result *HookResult) {
	return hook.ExecuteContext(context.Background())
}

// ExecuteOptional executes an optional hook, logs if it doesn't
// exist, and returns a printable error.
func (hook *Hook) ExecuteOptional() error {
	hr := hook.Execute()
	switch hr.ExitStatus {
	case HOOK_DOES_NOT_EXIST:
		log.Info(fmt.Sprintf("%v hook doesn't exist", hook.Name))
	case HOOK_VTROOT_ERROR:
		log.Info(fmt.Sprintf("VTROOT not set, so %v hook doesn't exist", hook.Name))
	case HOOK_SUCCESS:
		// nothing to do here
	default:
		return fmt.Errorf("%v hook failed(%v): %v", hook.Name, hr.ExitStatus, hr.Stderr)
	}
	return nil
}

// ExecuteAsWritePipe will execute the hook as in a Unix pipe,
// directing output to the provided writer. It will return:
// - an io.WriteCloser to write data to.
// - a WaitFunc method to call to wait for the process to exit,
// that returns stderr and the cmd.Wait() error.
// - an error code and an error if anything fails.
func (hook *Hook) ExecuteAsWritePipe(out io.Writer) (io.WriteCloser, WaitFunc, int, error) {
	// Find the hook.
	cmd, status, err := hook.findHook(context.Background())
	if err != nil {
		return nil, nil, status, err
	}

	// Configure the process's stdin, stdout, and stderr.

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Read hook name, exit status, and stderr from the message to find why the script failed; fix the script or its inputs
  2. Run the hook manually with the same arguments/environment to reproduce the failure
  3. If the hook's absence should be tolerated but its failure shouldn't (or vice versa), use ExecuteOptional vs Execute appropriately

Example fix

// before: 'backup_hook hook failed(1): mysqldump: command not found'
// after: install dependency in the image / fix script PATH
RUN apt-get install -y mysql-client
Defensive patterns

Strategy: try-catch

Try / catch

if err := hook.ExecuteOptional(h); err != nil {
    // message contains: name, exit status, and the script's stderr
    return fmt.Errorf("hook execution failed: %w", err)
}

Prevention

When it happens

Trigger: Calling hook.ExecuteOptional where the hook exists and runs but exits non-zero (e.g. HOOK_STAT_FAILED, HOOK_TERMINATED, or a script returning nonzero), or the process is killed by a signal.

Common situations: Hook scripts with bugs or unmet dependencies (missing commands inside the script); scripts failing due to wrong environment/arguments; hooks killed by timeouts.

Related errors


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