vitessio/vitess · error
failure creating directory %s: %w
Error message
failure creating directory %s: %w
What it means
When the dump target is local filesystem (not object store flags), backupPreCheck() creates the target directory with os.MkdirAll(location, 0o750) because MySQL Shell does not create full paths. This error wraps the OS failure (permissions, read-only FS, bad path) when directory creation fails.
Source
Thrown at go/vt/mysqlctl/mysqlshellbackupengine.go:492
}
return fileutil.SafePathJoin(mysqlShellBackupLocation, dir, name)
}
func (be *MySQLShellBackupEngine) backupPreCheck(location string) error {
if mysqlShellBackupLocation == "" {
return fmt.Errorf("%w: no backup location set via --mysql-shell-backup-location", ErrMySQLShellPreCheck)
}
if mysqlShellFlags == "" || !strings.Contains(mysqlShellFlags, "--js") {
return fmt.Errorf("%w: at least the --js flag is required in the value of the flag --mysql-shell-flags", ErrMySQLShellPreCheck)
}
// make sure the target directory exists if the target location for the backup is not an object store
// (e.g. is the local filesystem) as MySQL Shell doesn't create the entire path beforehand:
if !isObjectStoreFlags(mysqlShellDumpFlags) {
err := os.MkdirAll(location, 0o750)
if err != nil {
return fmt.Errorf("failure creating directory %s: %w", location, err)
}
}
return nil
}
func (be *MySQLShellBackupEngine) restorePreCheck(ctx context.Context, params RestoreParams) (shouldDeleteUsers bool, err error) {
if mysqlShellFlags == "" {
return shouldDeleteUsers, fmt.Errorf("%w: at least the --js flag is required in the value of the flag --mysql-shell-flags", ErrMySQLShellPreCheck)
}
loadFlags := map[string]any{}
err = json.Unmarshal([]byte(mysqlShellLoadFlags), &loadFlags)
if err != nil {
return false, fmt.Errorf("%w: unable to parse JSON of load flags", ErrMySQLShellPreCheck)
}
if val, ok := loadFlags["updateGtidSet"]; !ok || val != "replace" {View on GitHub (pinned to 01a25a7d17)
Solutions
- Check the exact wrapped OS error (permission denied vs read-only vs not a directory) and fix the filesystem accordingly.
- Pre-create the backup location with correct ownership for the tablet process user and mode 0750.
- Verify the volume is mounted inside the container/pod.
- If backing up to object storage, ensure the dump flags are recognized by isObjectStoreFlags so the mkdir is skipped.
Example fix
// before: mkdir fails because parent is unwritable // failure creating directory /vt/backups/shard-0: mkdir /vt/backups: permission denied // after: provision directory before starting tablet sudo mkdir -p /vt/backups/shard-0 sudo chown vitess:vitess /vt/backups/shard-0 sudo chmod 0750 /vt/backups/shard-0
Defensive patterns
Strategy: validation
Validate before calling
if !isObjectStoreFlags(mysqlShellDumpFlags) {
if err := os.MkdirAll(location, 0o750); err != nil {
return fmt.Errorf("backup location %s unusable: %v", location, err)
}
if fi, err := os.Stat(location); err != nil || !fi.IsDir() {
return fmt.Errorf("backup location %s is not a directory", location)
}
} Try / catch
err := engine.ExecuteBackup(ctx, backupParams)
if err != nil && strings.Contains(err.Error(), "failure creating directory") {
// check mount, ownership, and SELinux before retrying
return err
} Prevention
- Provision and chown the backup directory in the deployment/init step.
- Ensure the backup volume is mounted in containers before tablet start.
- Run tablets as a user with write access to the configured location.
When it happens
Trigger: ExecuteBackup -> backupPreCheck with a non-object-store location string that cannot be created: permission denied, nonexistent/unmountable parent, path is actually a file, or read-only filesystem.
Common situations: Backup location on a volume not mounted in the container; directory owned by another user (mysqld runs as 'mysql' or 'vitess'); SELinux denial; location string typo colliding with an existing file.
Related errors
- cannot stat hook %v: %v
- unable to create file: %v
- could not create temp file: %v
- could not read existing file %v: %v
- could not back up existing %v: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/59600e30196bbf17.
Report an issue: GitHub.