boto/boto3 · error · ValueError
Either a boto3.Client or s3transfer.manager.TransferManager
Error message
Either a boto3.Client or s3transfer.manager.TransferManager must be provided
What it means
Raised by S3Transfer.__init__ when neither a client nor a manager argument is supplied. The S3Transfer facade delegates all transfers to an underlying s3transfer TransferManager, which it either receives directly (manager=) or builds from a boto3 client (client=). With neither provided it has nothing to drive transfers with, so it raises this ValueError immediately.
Source
Thrown at boto3/s3/transfer.py:412
resolved = {}
for init_arg, val in init_args.items():
if val is not None:
resolved[init_arg] = val
elif TRANSFER_CONFIG_SUPPORTS_CRT:
resolved[init_arg] = self.UNSET_DEFAULT
else:
resolved[init_arg] = self.DEFAULTS[init_arg]
return resolved
class S3Transfer:
ALLOWED_DOWNLOAD_ARGS = TransferManager.ALLOWED_DOWNLOAD_ARGS
ALLOWED_UPLOAD_ARGS = TransferManager.ALLOWED_UPLOAD_ARGS
ALLOWED_COPY_ARGS = TransferManager.ALLOWED_COPY_ARGS
def __init__(self, client=None, config=None, osutil=None, manager=None):
if not client and not manager:
raise ValueError(
'Either a boto3.Client or s3transfer.manager.TransferManager '
'must be provided'
)
if manager and any([client, config, osutil]):
raise ValueError(
'Manager cannot be provided with client, config, '
'nor osutil. These parameters are mutually exclusive.'
)
if config is None:
config = TransferConfig()
if osutil is None:
osutil = OSUtils()
if manager:
self._manager = manager
else:
self._manager = create_transfer_manager(client, config, osutil)
def upload_file(View on GitHub (pinned to c7b4afac23)
Solutions
- Pass an S3 client: transfer = boto3.s3.transfer.S3Transfer(boto3.client('s3')).
- Prefer the injected high-level API (s3.upload_file / s3.download_file) which constructs the transfer machinery for you and rarely requires S3Transfer directly.
- If supplying a custom TransferManager, pass it as manager= (and leave client/config/osutil unset).
Example fix
// before
transfer = boto3.s3.transfer.S3Transfer() # no client/manager
// after
client = boto3.client('s3')
transfer = boto3.s3.transfer.S3Transfer(client) Defensive patterns
Strategy: validation
Validate before calling
if client is None and manager is None:
raise ValueError('Pass either a client or a manager to S3Transfer')
transfer = boto3.s3.transfer.S3Transfer(client=client, manager=manager) Type guard
def has_transfer_basis(client, manager) -> bool:
return client is not None or manager is not None Try / catch
try:
transfer = boto3.s3.transfer.S3Transfer(client)
except ValueError as e:
if 'must be provided' in str(e):
transfer = boto3.s3.transfer.S3Transfer(boto3.client('s3')) Prevention
- Prefer the injected s3.upload_file / s3.download_file helpers over constructing S3Transfer directly.
- Always pass an existing S3 client when constructing S3Transfer.
- Construct the client once and reuse it across transfers.
When it happens
Trigger: Instantiating S3Transfer() with no arguments: boto3.s3.transfer.S3Transfer(). Also reachable by explicitly passing client=None, manager=None.
Common situations: Directly constructing the lower-level S3Transfer class instead of using the injected s3.upload_file/download_file helpers; refactor that dropped the client argument; passing the client into the wrong parameter name.
Related errors
- Manager cannot be provided with client, config, nor osutil.
- Filename must be a string or a path-like object
- The following transfer config options are invalid when prefe
- Fileobj must implement read
- Fileobj must implement write
AI-assisted analysis of boto/boto3@c7b4afac23 (2026-08-04).
Data as JSON: /data/errors/226664c0e24c98d2.json.
Report an issue: GitHub.