{"record":{"id":"59600e30196bbf17","repo":"vitessio/vitess","slug":"failure-creating-directory-s-w","errorCode":null,"errorMessage":"failure creating directory %s: %w","messagePattern":"failure creating directory (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/mysqlctl/mysqlshellbackupengine.go","lineNumber":492,"sourceCode":"\t}\n\treturn fileutil.SafePathJoin(mysqlShellBackupLocation, dir, name)\n}\n\nfunc (be *MySQLShellBackupEngine) backupPreCheck(location string) error {\n\tif mysqlShellBackupLocation == \"\" {\n\t\treturn fmt.Errorf(\"%w: no backup location set via --mysql-shell-backup-location\", ErrMySQLShellPreCheck)\n\t}\n\n\tif mysqlShellFlags == \"\" || !strings.Contains(mysqlShellFlags, \"--js\") {\n\t\treturn fmt.Errorf(\"%w: at least the --js flag is required in the value of the flag --mysql-shell-flags\", ErrMySQLShellPreCheck)\n\t}\n\n\t// make sure the target directory exists if the target location for the backup is not an object store\n\t// (e.g. is the local filesystem) as MySQL Shell doesn't create the entire path beforehand:\n\tif !isObjectStoreFlags(mysqlShellDumpFlags) {\n\t\terr := os.MkdirAll(location, 0o750)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failure creating directory %s: %w\", location, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (be *MySQLShellBackupEngine) restorePreCheck(ctx context.Context, params RestoreParams) (shouldDeleteUsers bool, err error) {\n\tif mysqlShellFlags == \"\" {\n\t\treturn shouldDeleteUsers, fmt.Errorf(\"%w: at least the --js flag is required in the value of the flag --mysql-shell-flags\", ErrMySQLShellPreCheck)\n\t}\n\n\tloadFlags := map[string]any{}\n\terr = json.Unmarshal([]byte(mysqlShellLoadFlags), &loadFlags)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"%w: unable to parse JSON of load flags\", ErrMySQLShellPreCheck)\n\t}\n\n\tif val, ok := loadFlags[\"updateGtidSet\"]; !ok || val != \"replace\" {","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/mysqlctl/mysqlshellbackupengine.go#L474-L510","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: mkdir fails because parent is unwritable\n// failure creating directory /vt/backups/shard-0: mkdir /vt/backups: permission denied\n// after: provision directory before starting tablet\nsudo mkdir -p /vt/backups/shard-0\nsudo chown vitess:vitess /vt/backups/shard-0\nsudo chmod 0750 /vt/backups/shard-0","handlingStrategy":"validation","validationCode":"if !isObjectStoreFlags(mysqlShellDumpFlags) {\n\tif err := os.MkdirAll(location, 0o750); err != nil {\n\t\treturn fmt.Errorf(\"backup location %s unusable: %v\", location, err)\n\t}\n\tif fi, err := os.Stat(location); err != nil || !fi.IsDir() {\n\t\treturn fmt.Errorf(\"backup location %s is not a directory\", location)\n\t}\n}","typeGuard":null,"tryCatchPattern":"err := engine.ExecuteBackup(ctx, backupParams)\nif err != nil && strings.Contains(err.Error(), \"failure creating directory\") {\n\t// check mount, ownership, and SELinux before retrying\n\treturn err\n}","preventionTips":["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."],"tags":["backup","mysqlshell","filesystem","permissions"],"backgroundTag":"directory-creation-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}