You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang httpClient调用Minio预签名PUT URL返回MissingContentLength错误求助

问题根因

你遇到的报错是Go标准库net/http的实现逻辑和Minio预签名接口的约束共同导致的:

  • Go标准库net/http中,Content-Length由http.Request结构体的ContentLength字段独立控制,手动往Request.Header中设置Content-Length不会生效,发起请求时会被客户端忽略
  • 当ContentLength未显式赋值时,http.Client默认会对os.File类型的请求体使用分块传输编码,而Minio的预签名PUT接口不支持分块传输,因此强制要求请求必须携带Content-Length头
  • curl的--upload-file参数会自动读取文件大小并显式设置Content-Length,因此可以正常上传
解决方案

只需要在原有代码的基础上,把读取到的文件大小赋值给request.ContentLength字段即可,修正后的代码如下:

url := "http://pre-signed-url-to-bucket-obj"
fileName := "test.txt"

file, err := os.Open(fileName)
if err != nil {
    log.Fatal(err)
}
defer file.Close()

// 读取文件大小
fStat, err := file.Stat()
if err != nil {
  log.Fatal("Error getting file info:", err)
}

request, err := http.NewRequest(http.MethodPut, url, file)
if err != nil {
    log.Fatal("Error creating request:", err)
}

// 直接给Request的ContentLength字段赋值,不要往Header里写
request.ContentLength = fStat.Size()

client := &http.Client{}
resp, err := client.Do(request)
if err != nil {
    log.Fatal("Error performing request:", err)
}
defer resp.Body.Close()

content, err := ioutil.ReadAll(resp.Body)
if err != nil {
    log.Fatal("Error reading response:", err)
}

log.Println(string(content))
额外注意事项
  • 如果上传的是内存字节流,将[]byte包装为bytes.Reader传入http.NewRequest,标准库会自动识别可寻址的请求体,自动填充ContentLength字段,不需要手动处理
  • 不要使用分块传输的请求体调用Minio预签名PUT接口,服务端会直接拒绝

内容的提问来源于stack exchange,提问作者Cirrith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:15:02