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

使用Paramiko向SFTP服务器传输大文件时遇OSError: Failure错误

问题描述

运行在Windows Server 2016 Standard虚拟机上的Python脚本,通过任务计划程序执行,需将共享驱动器上的4个文件(大小分别为25MB、55MB、900MB、2GB)上传至SFTP服务器。前三个小文件上传成功,但2GB的大文件上传时触发OSError: Failure,且报错后数小时内无法上传任何文件——即使小文件也会立即报错,需等待数小时或次日才能恢复。

上传代码

hostname = 'ftp_server_name'
username = 'username'
password = 'password'
keypath = 'Sftp_Key'
known_hosts = 'known_hosts.txt'

import paramiko

mykey = paramiko.RSAKey.from_private_key_file(keypath, password)

ssh_client = paramiko.SSHClient()
ssh_client.load_host_keys(known_hosts)
ssh_client.connect(
    hostname=hostname,
    username=username,
    allow_agent=True,
    pkey=mykey,
    disabled_algorithms={'pubkeys': ['rsa-sha2-256', 'rsa-sha2-512']}
)

tr = ssh_client.get_transport()
tr.default_max_packet_size = 10000000000
tr.default_window_size = 10000000000

sftp_client = ssh_client.open_sftp()

sftp_client.put(
    r'\\path\to\origin\on\shared\drive\file_1.csv',
    '/root/folder/path/to/destination/file_1.csv'
)

sftp_client.put(
    r'\\path\to\origin\on\shared\drive\file_2.csv',
    '/root/folder/path/to/destination/file_2.csv'
)

sftp_client.put(
    r'\\path\to\origin\on\shared\drive\file_3.csv',
    '/root/folder/path/to/destination/file_3.csv'
)

sftp_client.put(
    r'\\path\to\origin\on\shared\drive\file_4.csv',
    '/root/folder/path/to/destination/file_4.csv'
)
print(sftp_client.listdir())

sftp_client.close()
ssh_client.close()

错误堆栈

Traceback (most recent call last):

  File "H:\folder\scripts\test_sftp_copy.py", line 45, in <module>
    ftp_client.put(

  File "C:\Users\MeUser\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 759, in put
    return self.putfo(fl, remotepath, file_size, callback, confirm)

  File "C:\Users\MeUser\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 716, in putfo
    size = self._transfer_with_callback(

  File "C:\Users\MeUser\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 679, in _transfer_with_callback
    writer.write(data)

  File "C:\Users\MeUser\Anaconda3\lib\site-packages\paramiko\file.py", line 405, in write
    self._write_all(data)

  File "C:\Users\MeUser\Anaconda3\lib\site-packages\paramiko\file.py", line 522, in _write_all
    count = self._write(data)

  File "C:\Users\MeUser\Anaconda3\lib\site-packages\paramiko\sftp_file.py", line 208, in _write
    t, msg = self.sftp._read_response(req)

  File "C:\Users\A-AChiap\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 874, in _read_response
    self._convert_status(msg)

  File "C:\Users\A-AChiap\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 907, in _convert_status
    raise IOError(text)

OSError: Failure.

技术分析

  1. 大文件上传失败原因

    • 服务器端限制:多数SFTP服务器(如OpenSSH)默认对单个文件大小、会话传输量或用户磁盘配额有上限,2GB文件可能触发这类限制,或目标磁盘空间不足。
    • 参数配置过载:你设置的default_max_packet_size和default_window_size(10GB)远超SFTP协议常规范围(通常最大1GB),可能导致服务器缓冲区溢出,直接中断会话。
    • 网络与会话异常:大文件传输时长久,网络波动可能导致会话半开,服务器未正确处理中断后的资源回收。
  2. 报错后无法上传的原因

    • 服务器资源锁定:大文件上传失败时,服务器可能未释放残留的会话资源(如文件句柄、内存缓冲区),导致该用户的后续请求被拒绝,直到服务器自动回收资源或会话超时。
    • 临时封禁机制:部分SFTP服务器会对异常中断的会话IP/用户进行临时封禁,防止恶意请求,封禁时长通常为几小时。

解决建议

1. 调整传输参数

将数据包大小和窗口大小调整为合理范围,建议设置为64MB(67108864),平衡传输效率与服务器负载:

tr.default_max_packet_size = 67108864
tr.default_window_size = 67108864

2. 分块传输大文件

使用putfo配合分块读取,避免一次性加载大文件到内存,降低单次传输压力:

def upload_large_file(sftp, local_path, remote_path, chunk_size=67108864):
    with open(local_path, 'rb') as f:
        sftp.putfo(f, remote_path, callback=lambda transferred, total: print(f"Transferred {transferred}/{total} bytes"))

# 替换原有的file_4.csv上传代码
upload_large_file(sftp_client, r'\\path\to\origin\on\shared\drive\file_4.csv', '/root/folder/path/to/destination/file_4.csv')

3. 强制会话清理

添加异常捕获与强制关闭逻辑,确保上传失败时释放所有会话资源:

try:
    # 上传文件的代码块
    sftp_client.put(...)
    upload_large_file(...)
    print(sftp_client.listdir())
except Exception as e:
    print(f"Upload failed: {str(e)}")
finally:
    # 确保会话关闭,忽略关闭时的异常
    try:
        sftp_client.close()
    except:
        pass
    try:
        ssh_client.close()
    except:
        pass

4. 服务器端排查

  • 检查目标目录磁盘空间,确保能容纳2GB文件。
  • 查看服务器日志(如OpenSSH的/var/log/auth.log或/var/log/sftp.log),确认失败时的具体错误信息,排查是否存在文件大小限制、配额不足或资源耗尽记录。
  • 调整服务器SFTP配置(如sshd_config中的MaxSessions、MaxStartups参数),增加会话数上限,避免资源耗尽。
  • 确认服务器是否有临时封禁机制,调整超时时间或添加白名单。

5. 任务计划优化

  • 在任务计划程序中设置失败后重试机制,添加15分钟以上的重试间隔,避免短时间内频繁请求触发封禁。
  • 验证脚本运行用户对共享驱动器的读取权限,防止大文件读取时出现权限问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:35:05