flipped-aurora/gin-vue-admin · error

function file.Open() failed, err:

Error message

function file.Open() failed, err:

What it means

Wraps the error from multipart.File's Open() (the *multipart.FileHeader.Open call) in the AwsS3 UploadFile implementation. file.Open() reads the uploaded part into memory or a temp file; it fails only when the multipart stream is broken, truncated, or the temp file cannot be created. The wrapper logs it with the upload module logger and returns it to the Service layer.

Source

Thrown at server/utils/upload/aws_s3.go:43

//@object: *AwsS3
//@function: UploadFile
//@description: Upload file to Aws S3 using aws-sdk-go-v2. See https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/s3-example-basic-bucket-operations.html
//@param: file *multipart.FileHeader
//@return: string, string, error

func (*AwsS3) UploadFile(ctx context.Context, file *multipart.FileHeader) (string, string, error) {
	client, err := newS3Client()
	if err != nil {
		return "", "", err
	}
	uploader := manager.NewUploader(client)

	fileKey := fmt.Sprintf("%d%s", time.Now().Unix(), file.Filename)
	filename := global.GVA_CONFIG.AwsS3.PathPrefix + "/" + fileKey
	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 关闭

	_, err = uploader.Upload(context.TODO(), &s3.PutObjectInput{
		Bucket:      aws.String(global.GVA_CONFIG.AwsS3.Bucket),
		Key:         aws.String(filename),
		Body:        f,
		ContentType: aws.String(file.Header.Get("Content-Type")),
	})
	if err != nil {
		logger.WithCtx(ctx).Mod("upload").Err(err).Error("function uploader.Upload() failed")
		return "", "", err
	}

	return global.GVA_CONFIG.AwsS3.BaseURL + "/" + filename, fileKey, nil
}

//@author: [WqyJh](https://github.com/WqyJh)

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Increase nginx/proxy client_max_body_size and request timeouts so large uploads are not truncated mid-stream
  2. Check the server temp directory exists, is writable, and has free space (TMPDIR) for multipart spooling
  3. Ensure no middleware consumed c.Request.Body (e.g. a prior ParseMultipartForm or body-logging middleware) before UploadFile runs
  4. Return a 4xx to the client with retry guidance when the multipart stream is aborted; the client should re-send the file

Example fix

// before
// middleware already drained the body
body, _ := io.ReadAll(c.Request.Body)
// after
// do not consume c.Request.Body before form parsing/upload
fileHeader, err := c.FormFile("file")
if err != nil { return err }
_, _, err = uploadOss.UploadFile(fileHeader)
Defensive patterns

Strategy: validation

Validate before calling

fh, err := c.FormFile("file")
if err != nil { return nil, fmt.Errorf("multipart part missing or invalid: %w", err) }
if fh.Size <= 0 { return nil, errors.New("uploaded file is empty") }
if fh.Size > maxUploadSize { return nil, fmt.Errorf("file exceeds %d bytes", maxUploadSize) }
f, err := fh.Open()
if err == nil { defer f.Close() } // fail before calling the upload util

Try / catch

url, _, err := s3Store.UploadFile(fileHeader)
if err != nil {
    if strings.Contains(err.Error(), "file.Open() failed") {
        return "", fmt.Errorf("upload stream broken, please retry the upload: %w", err)
    }
    return "", err
}

Prevention

When it happens

Trigger: Calling UploadFile with a *multipart.FileHeader whose underlying request body was already consumed or aborted mid-stream, the client disconnected during upload, the uploaded part exceeds memory limits and the OS refuses to create a spool temp file, or a corrupted multipart request.

Common situations: Reverse proxy (nginx) buffering limits aborting large uploads; client timeout canceling the request before the file is fully read; missing server temp dir space / read-only /tmp; handler reading c.Request.Body before the upload util does.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/3c1605612d4fff7b. Report an issue: GitHub.