flipped-aurora/gin-vue-admin · error

function io.Copy() failed, err:

Error message

function io.Copy() failed, err:

What it means

This error is returned by Local.UploadFile when io.Copy(out, f) fails while streaming the uploaded multipart file content into the newly created local file. It indicates an I/O failure reading from the multipart source (client disconnect) or writing to the local file (disk full, I/O error). The underlying error is appended to the message.

Source

Thrown at server/utils/upload/local.go:69

	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())
	}
	defer out.Close() // 创建文件 defer 关闭

	_, copyErr := io.Copy(out, f) // 传输(拷贝)文件
	if copyErr != nil {
		logger.WithCtx(ctx).Mod("upload").Err(copyErr).Error("function io.Copy() failed")
		return "", "", errors.New("function io.Copy() failed, err:" + copyErr.Error())
	}
	return filepath, filename, nil
}

//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Local
//@function: DeleteFile
//@description: 删除文件
//@param: key string
//@return: error

func (l *Local) DeleteFile(ctx context.Context, key string) error {
	p, err := l.localPath(ctx, key)
	if err != nil {
		return err
	}

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Check the appended OS error: if 'broken pipe'/'unexpected EOF', it is a client-side disconnect — retry from the client or increase client/proxy timeouts.
  2. If 'no space left on device', free disk space or expand the volume; consider rejecting uploads larger than available space up front.
  3. Add a reverse-proxy (nginx) client_max_body_size and timeout configuration aligned with expected upload sizes.
  4. Delete the partially written file if you want to avoid orphaned partials, since the function returns without cleanup.

Example fix

// before
server on 99% disk; large upload -> "function io.Copy() failed, err: write uploads/x.png: no space left on device"
// after
# shell
df -h && du -sh /var/log/* | sort -h   # free space or expand volume, then retry the upload
Defensive patterns

Strategy: retry

Validate before calling

// before upload, check headroom
func hasDiskHeadroom(storePath string, need uint64) (bool, error) {
    var st syscall.Statfs_t
    if err := syscall.Statfs(storePath, &st); err != nil {
        return false, err
    }
    return uint64(st.Bavail)*uint64(st.Bsize) > need, nil
}

Try / catch

filePath, filename, err := local.UploadFile(ctx, fileHeader)
if err != nil {
    if strings.HasPrefix(err.Error(), "function io.Copy() failed") {
        // transient I/O: allow client retry; log the appended OS error to classify
        return nil // or requeue with backoff
    }
    return err
}

Prevention

When it happens

Trigger: UploadFile was called, the destination file was created successfully, but copying the body failed: client aborted the upload mid-transfer, network interruption between client and server, disk became full during the write, or the local disk reported an I/O error.

Common situations: Large file uploads over unstable mobile connections where the client disconnects; servers with nearly-full disks where small uploads succeed but large ones hit ENOSPC; NFS/CIFS-mounted storage dropping connections.

Related errors


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