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

部署服务器使用AWS SDK上传S3文件报传输流意外EOF错误

问题现象

使用AWS SDK向S3存储桶上传文件时,本地环境运行一切正常,部署到线上服务器后触发报错:

Received an unexpected EOF or 0 bytes from the transport stream.

核心上传逻辑代码如下:

var location = $"some-location";
using (var stream = request.File.OpenReadStream())
{
    var putRequest = new PutObjectRequest
    {
        Key = location,
        BucketName = configuration["AWS:BucketName"],
        InputStream = stream,
        AutoCloseStream = true,
        ContentType = request.File.ContentType
    };
    var putResponse = await amazonS3.PutObjectAsync(putRequest);

    response.IsValid = putResponse.HttpStatusCode == System.Net.HttpStatusCode.OK;
}

上述代码中request.File为FormFile类型,通过如下控制器接口传入:

public async Task<UploadResponse> Upload(IFormFile formFile)
{
    if (formFile is null || formFile.Length <= 0)
    {
        throw new ArgumentNullException(nameof(formFile));
    }

    //TODO: Validate File Extension

    UploadResponse response;

    UploadCommand command = new UploadCommand();
    command.File = formFile;

    response = await mediator.Send(command);

    return response;
}
常见诱发原因
  • TLS协议版本不匹配:当前AWS S3所有接口强制要求使用TLS 1.2及以上版本建立连接,本地开发环境通常系统版本较新、默认启用高版本TLS,线上服务器(尤其是低版本Windows Server、旧版.NET运行环境)默认未开启TLS 1.2支持,握手阶段会被S3直接断开连接,触发流终止错误。
  • 文件流状态异常:IFormFile流在MediatR传递链路中如果被其他逻辑提前读取过,且未将流指针重置回起始位置,会导致AWS SDK实际读取流时拿到空内容,触发0字节传输报错;另外线上部署的反向代理、Web服务器默认请求体大小限制小于上传文件尺寸时,会主动截断上传请求,导致连接中断。
  • 网络链路拦截:线上环境出口防火墙、安全组、上网代理未放通S3服务端点的443端口出站权限,或对HTTPS长连接设置了过短的超时时间,会导致上传过程中连接被中途切断,抛出EOF错误。
修复方案
  • 配置全局TLS版本支持
    在程序启动入口(ASP.NET Core的Program.cs、.NET Framework的Global.asax.cs)添加如下配置,强制出站请求使用兼容的TLS版本:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls13;

如果使用Windows Server作为运行环境,可同步在系统注册表中开启TLS 1.2的系统级支持,避免其他组件受协议版本限制。

  • 修正流读取与上传配置
    在读取IFormFile流执行上传前,主动重置流位置到起始点,避免流被提前消费导致空读;大文件场景开启分块编码,降低长连接超时概率:
using (var stream = request.File.OpenReadStream())
{
    // 重置流指针到起始位置
    if (stream.CanSeek)
    {
        stream.Position = 0;
    }
    var putRequest = new PutObjectRequest
    {
        Key = location,
        BucketName = configuration["AWS:BucketName"],
        InputStream = stream,
        AutoCloseStream = true,
        ContentType = request.File.ContentType,
        // 开启分块编码适配大文件上传
        UseChunkEncoding = true
    };
    var putResponse = await amazonS3.PutObjectAsync(putRequest);
    response.IsValid = putResponse.HttpStatusCode == System.Net.HttpStatusCode.OK;
}

同步调整Web服务器(Kestrel/IIS)、前置反向代理(Nginx/APISIX等)的最大请求体限制,匹配业务要求的最大上传文件尺寸,避免请求被中间层截断。

  • 排查网络连通性
    在线上服务器本地测试S3对应区域端点的443端口连通性,确认出口防火墙、安全组未拦截相关流量;如果环境要求统一走HTTP代理出站,需在AWS SDK配置中显式指定代理地址与认证信息,避免代理隐式拦截上传连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:30:43