boto/boto3 · error · ValueError

Manager cannot be provided with client, config, nor osutil…

Error message

Manager cannot be provided with client, config, nor osutil. These parameters are mutually exclusive.

What it means

Raised by the `S3Transfer` constructor when a `manager` (a pre-built `TransferManager`) is passed alongside any of `client`, `config`, or `osutil`. These are mutually exclusive: when you supply your own manager, boto3 must not override its internal client/config/osutil. Pick one mode — delegate construction (pass `client`) or bring your own manager.

Solutions

  1. If you only need custom config, drop `manager` and pass `client` + `config`: `S3Transfer(client=s3, config=cfg)`.
  2. If you built a fully custom manager, drop `client`, `config`, and `osutil`: `S3Transfer(manager=my_manager)`.
  3. Audit the call site and pass arguments from only one of the two groups.

Example fix

# before
from boto3.s3.transfer import S3Transfer, TransferConfig
transfer = S3Transfer(client=s3, config=TransferConfig(), manager=mgr)

# after (delegate mode)
transfer = S3Transfer(client=s3, config=TransferConfig())
# after (custom-manager mode)
transfer = S3Transfer(manager=mgr)
Defensive patterns

Strategy: validation

Validate before calling

def build_transfer(client=None, config=None, osutil=None, manager=None):
    if manager:
        assert not any([client, config, osutil]), 'manager is mutually exclusive with client/config/osutil'
    else:
        assert client, 'client required when manager is absent'
    from boto3.s3.transfer import S3Transfer
    return S3Transfer(client=client, config=config, osutil=osutil, manager=manager)

Type guard

def manager_only_kwargs(client, config, osutil, manager) -> bool:
    return bool(manager) and not any([client, config, osutil])

Try / catch

try:
    t = S3Transfer(client=s3, config=cfg, manager=mgr)
except ValueError:
    t = S3Transfer(client=s3, config=cfg)  # drop the manager

Prevention

When it happens

Trigger: Calling `S3Transfer(client=s3_client, config=cfg, osutil=OSUtils(), manager=my_manager)` (any combination where `manager` and at least one of the others are non-None). Often a partial refactor that added a manager while leaving the old arguments in place.

Common situations: Migrating from client-based construction to a custom manager and forgetting to remove the now-redundant `client=`/`config=` kwargs; copy-pasting a custom TransferManager example onto existing S3Transfer code.

Related errors


AI-assisted analysis of boto/boto3@6e10b029c1 (2026-08-11). Data as JSON: /api/errors/21650a2d622ee887. Report an issue: GitHub.

Appendix: source

Thrown at boto3/s3/transfer.py:417

                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(
        self, filename, bucket, key, callback=None, extra_args=None
    ):
        """Upload a file to an S3 object.

        Variants have also been injected into S3 client, Bucket and Object.

View on GitHub (pinned to 6e10b029c1)