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 the `S3Transfer` constructor when neither `client` nor `manager` is supplied. `S3Transfer` needs either a low-level `boto3.client('s3')` to build its own internal manager, or a pre-built `s3transfer.manager.TransferManager`. Most users never instantiate `S3Transfer` directly because the convenience methods on `client`, `Bucket`, and `Object` already wire one up.
Solutions
- Prefer the injected helpers (`client.upload_file`, `bucket.download_file`) — they construct S3Transfer correctly for you.
- If you must build it, pass the client: `S3Transfer(client=s3_client)`.
- Ensure the client is created before the transfer: `s3 = boto3.client('s3'); transfer = S3Transfer(client=s3)`.
- Add an assert to catch None early: `assert s3_client is not None`.
Example fix
# before
from boto3.s3.transfer import S3Transfer
transfer = S3Transfer() # ValueError: Either a boto3.Client or ... must be provided
# after
import boto3
transfer = S3Transfer(client=boto3.client('s3'))
# better: use the injected helper directly
boto3.client('s3').upload_file('/tmp/f', 'bucket', 'key') Defensive patterns
Strategy: validation
Validate before calling
def make_transfer(client=None, manager=None):
assert client or manager, 'S3Transfer requires client or manager'
from boto3.s3.transfer import S3Transfer
return S3Transfer(client=client, manager=manager) Type guard
def has_client_or_manager(client, manager) -> bool:
return bool(client) or bool(manager) Try / catch
try:
transfer = S3Transfer(client=s3)
except ValueError:
s3 = boto3.client('s3')
transfer = S3Transfer(client=s3) Prevention
- Prefer the injected helpers (client.upload_file/download_file) over constructing S3Transfer.
- Create the S3 client in one place and reuse it.
- Assert the client is not None before building a transfer.
When it happens
Trigger: Calling `S3Transfer()` with all-default arguments, or explicitly `S3Transfer(client=None, manager=None)`. Also when a variable intended to hold the client is None due to a failed/unevaluated client creation.
Common situations: Copy-pasting an example that constructs `S3Transfer` but forgetting to pass the client; refactoring code that previously passed `client=` and accidentally dropping it; the client creation failed earlier and the None propagated.
Related errors
- Manager cannot be provided with client, config, nor osutil…
- CRT transfer client is configured but is missing minimum…
- Filename must be a string or a path-like object
- Max Retries Exceeded
- The following transfer config options are invalid when…
AI-assisted analysis of boto/boto3@6e10b029c1 (2026-08-11).
Data as JSON: /api/errors/226664c0e24c98d2.
Report an issue: GitHub.
Appendix: 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 6e10b029c1)