部署服务器使用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
相关产品推荐
相关产品推荐

