flipped-aurora/gin-vue-admin · error
function os.MkdirAll() failed, err:
Error message
function os.MkdirAll() failed, err:
What it means
local.UploadFile creates the configured store directory with os.MkdirAll before writing the uploaded file. If the OS refuses (permission denied, path is a file, read-only filesystem), the mkdirErr is wrapped in this message and the upload aborts. This is purely a filesystem/permissions problem, not a network one.
Source
Thrown at server/utils/upload/local.go:45
//@object: *Local
//@function: UploadFile
//@description: 上传文件
//@param: file *multipart.FileHeader
//@return: string, string, error
func (*Local) UploadFile(ctx context.Context, file *multipart.FileHeader) (string, string, error) {
// 读取文件后缀
ext := filepath.Ext(file.Filename)
// 读取文件名并加密
name := strings.TrimSuffix(file.Filename, ext)
name = utils.MD5V([]byte(name))
// 拼接新文件名
filename := name + "_" + time.Now().Format("20060102150405") + ext
// 尝试创建此路径
mkdirErr := os.MkdirAll(global.GVA_CONFIG.Local.StorePath, os.ModePerm)
if mkdirErr != nil {
logger.WithCtx(ctx).Mod("upload").Err(mkdirErr).Error("function os.MkdirAll() failed")
return "", "", errors.New("function os.MkdirAll() failed, err:" + mkdirErr.Error())
}
// 拼接路径和文件名
p := global.GVA_CONFIG.Local.StorePath + "/" + filename
filepath := global.GVA_CONFIG.Local.Path + "/" + filename
f, openError := file.Open() // 读取文件
if openError != nil {
logger.WithCtx(ctx).Mod("upload").Err(openError).Error("function file.Open() failed")
return "", "", errors.New("function file.Open() failed, err:" + openError.Error())
}
defer f.Close() // 创建文件 defer 关闭
out, createErr := os.Create(p)
if createErr != nil {
logger.WithCtx(ctx).Mod("upload").Err(createErr).Error("function os.Create() failed")
return "", "", errors.New("function os.Create() failed, err:" + createErr.Error())
}View on GitHub (pinned to 3136500ef3)
Solutions
- Check the wrapped err text: 'permission denied' -> chown/chmod the StorePath parent for the server's user
- Confirm the path in config Local.StorePath is correct and not colliding with an existing file
- If running in Docker/K8s, ensure the volume is mounted read-write
- On systemd, review hardening options (ProtectSystem, ReadOnlyPaths) or add ReadWritePaths for the store path
- Check disk space and mount status (df -h, mount) for read-only remounts after errors
Example fix
// before store-path: /var/lib/gva/uploads # owned by root, server runs as gva // after # sudo mkdir -p /var/lib/gva/uploads && sudo chown gva:gva /var/lib/gva/uploads
Defensive patterns
Strategy: validation
Validate before calling
storePath := global.GVA_CONFIG.Local.StorePath
if fi, err := os.Stat(storePath); err == nil && !fi.IsDir() {
return fmt.Errorf("%s exists and is not a directory", storePath)
}
if err := os.MkdirAll(storePath, os.ModePerm); err != nil {
return fmt.Errorf("store path not writable: %w", err)
} Type guard
null
Try / catch
url, name, err := uploader.UploadFile(ctx, fileHeader, fileName)
if err != nil {
if strings.Contains(err.Error(), "os.MkdirAll() failed") {
logger.Error("store path unusable — check permissions/mount", zap.Error(err))
return c.JSON(500, gin.H{"msg": "storage path unavailable"})
}
return err
} Prevention
- Create and chown the store path in deployment scripts/Dockerfile before start
- Run the server as a user with write access to the store path
- Check systemd hardening (ReadOnlyPaths/ProtectSystem) and Docker volume rw flags
- Add a startup preflight that MkdirAll's the store path and fails fast on error
- Monitor disk space and read-only remounts on the storage volume
When it happens
Trigger: UploadFile(ctx, file, ...) when global.GVA_CONFIG.Local.StorePath cannot be created: parent directory lacks write permission, a regular file exists at that path, the disk is read-only or full, or the path is invalid for the OS.
Common situations: Docker volume mounted read-only, StorePath configured under /root without privileges, SELinux/AppArmor denials, systemd service with restrictive ProtectSystem/ReadOnlyPaths, config pointing at a path where a file (e.g. a bind-mounted file) already exists.
Related errors
- function file.Open() failed, err:
- function os.Create() failed, err:
- 文件删除失败:
- function os.ReadDir() failed, err:
- 创建编译根目录失败: %w
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/0eb6966e5a46cb56.
Report an issue: GitHub.