vitessio/vitess · error

can't open init-db-sql-file (%v): %v

Error message

can't open init-db-sql-file (%v): %v

What it means

When a custom init-db-sql-file is configured, Vitess opens that SQL file to read the initialization script before feeding it to the mysql client. If os.Open fails (file missing, wrong path, permission denied), Init aborts with this error naming the file and the OS error. Nothing has been executed yet, so mysqld startup stops before applying any init SQL.

Source

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

		return err
	}
	if initDBSQLFile == "" { // default to built-in
		if err := mysqld.executeMysqlScript(ctx, params, config.DefaultInitDB); err != nil {
			return fmt.Errorf("failed to initialize mysqld: %v", err)
		}
		// Execute clone-specific init SQL if enabled
		if mysqlCloneEnabled {
			if err := mysqld.executeMysqlScript(ctx, params, config.InitClone); err != nil {
				return fmt.Errorf("failed to initialize clone support: %v", err)
			}
		}
		return nil
	}

	// else, user specified an init db file
	sqlFile, err := os.Open(initDBSQLFile)
	if err != nil {
		return fmt.Errorf("can't open init-db-sql-file (%v): %v", initDBSQLFile, err)
	}
	defer sqlFile.Close()
	script, err := io.ReadAll(sqlFile)
	if err != nil {
		return fmt.Errorf("can't read init-db-sql-file (%v): %v", initDBSQLFile, err)
	}
	if err := mysqld.executeMysqlScript(ctx, params, string(script)); err != nil {
		return fmt.Errorf("can't run init-db-sql-file (%v): %v", initDBSQLFile, err)
	}
	return nil
}

// For debugging purposes show the last few lines of the MySQL error log.
// Return a suggestion (string) if the file is non regular or can not be opened.
// This helps prevent cases where the error log is symlinked to /dev/stderr etc,
// In which case the user can manually open the file.
func readTailOfMysqldErrorLog(fileName string) string {
	fileInfo, err := os.Stat(fileName)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Verify the -init_db_sql_file path exists and is spelled correctly (use an absolute path).
  2. Fix file permissions so the user running mysqlctl/vttablet can read it.
  3. Confirm the file is present inside the container/mount if running containerized.
  4. Point the flag at a regular file, not a directory or symlink to a missing target.

Example fix

// before
-init_db_sql_file ./init.sql   # relative path, wrong cwd
// after
-init_db_sql_file /vt/config/init_db.sql
Defensive patterns

Strategy: validation

Validate before calling

if fi, err := os.Stat(initDBSQLFile); err != nil {
    return fmt.Errorf("init db sql file missing: %w", err)
} else if fi.IsDir() {
    return fmt.Errorf("%s is a directory", initDBSQLFile)
} else if f, err := os.OpenFile(initDBSQLFile, os.O_RDONLY, 0); err != nil {
    return fmt.Errorf("init db sql file unreadable: %w", err)
} else {
    f.Close()
}

Type guard

func readableFile(p string) bool {
    fi, err := os.Stat(p)
    return err == nil && fi.Mode().IsRegular()
}

Try / catch

if err := mysqld.Start(ctx, cnf, mysqldArgs, params); err != nil && strings.Contains(err.Error(), "can't open init-db-sql-file") {
    // fix the path/permissions reported in the message and retry
}

Prevention

When it happens

Trigger: Mysqld.Start/Init with initDBSQLFile set calls os.Open(initDBSQLFile) and the open fails: ENOENT (file absent), EACCES (no read permission), EISDIR (path is a directory).

Common situations: Typo or wrong absolute path in the -init_db_sql_file flag; file not mounted/copied into a container; the Vitess process user cannot read the file (root-owned, mode 0600); passing a directory instead of a file.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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