{"record":{"id":"600f47727fc1ff3d","repo":"boto/boto3","slug":"the-following-transfer-config-options-are-invalid","errorCode":null,"errorMessage":"The following transfer config options are invalid when preferred_transfer_client is set to crt: {invalid_crt_args}`","messagePattern":"The following transfer config options are invalid when preferred_transfer_client is set to crt: (.+?)`","errorType":"exception","errorClass":"InvalidCrtTransferConfigError","httpStatus":null,"severity":"error","filePath":"boto3/crt.py","lineNumber":193,"sourceCode":"\ndef _validate_crt_transfer_config(config):\n    if config is None:\n        return\n    # CRT client can also be configured via `AUTO_RESOLVE_TRANSFER_CLIENT`\n    # but it predates this validation. We only validate against CRT client\n    # configured via `CRT_TRANSFER_CLIENT` to preserve compatibility.\n    if config.preferred_transfer_client != CRT_TRANSFER_CLIENT:\n        return\n    invalid_crt_args = []\n    for param in config.DEFAULTS.keys():\n        val = config.get_deep_attr(param)\n        if (\n            param not in _ALLOWED_CRT_TRANSFER_CONFIG_OPTIONS\n            and val is not config.UNSET_DEFAULT\n        ):\n            invalid_crt_args.append(param)\n    if len(invalid_crt_args) > 0:\n        raise InvalidCrtTransferConfigError(\n            \"The following transfer config options are invalid \"\n            \"when preferred_transfer_client is set to crt: \"\n            f\"{', '.join(invalid_crt_args)}`\"\n        )\n\n\ndef create_crt_transfer_manager(client, config):\n    \"\"\"Create a CRTTransferManager for optimized data transfer.\"\"\"\n    crt_s3_client = get_crt_s3_client(client, config)\n    if is_crt_compatible_request(client, crt_s3_client):\n        crt_transfer_manager_kwargs = {\n            'crt_s3_client': crt_s3_client.crt_client,\n            'crt_request_serializer': BOTOCORE_CRT_SERIALIZER,\n        }\n        if TRANSFER_CONFIG_SUPPORTS_CRT:\n            _validate_crt_transfer_config(config)\n            crt_transfer_manager_kwargs['config'] = config\n        if not TRANSFER_CONFIG_SUPPORTS_CRT and config:","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/boto/boto3/blob/6e10b029c1326a437932a8b24f38af69fd986e15/boto3/crt.py#L175-L211","documentation":"Raised by boto3's CRT (C Runtime) transfer integration when preferred_transfer_client is set to 'crt' but the TransferConfig also contains options that the CRT client does not honor. boto3 inspects config.DEFAULTS and, for every key not in _ALLOWED_CRT_TRANSFER_CONFIG_OPTIONS (multipart_threshold, max_concurrency, max_request_concurrency, multipart_chunksize, preferred_transfer_client), if the value differs from UNSET_DEFAULT it is collected and rejected. The goal is to fail fast rather than silently ignore a tuning knob the user believes is active.","triggerScenarios":"Calling boto3.client('s3').upload_file/download_file (or any TransferManager-backed operation) with a botocore.transfer.TransferConfig where preferred_transfer_client='crt' and a disallowed attribute (e.g. use_threads, max_bandwidth, num_download_attempts, io_chunksize) is set to a non-default value.","commonSituations":"Migrating from the default threaded transfer client to the CRT client and reusing the existing TransferConfig verbatim; copy-pasting a tuning recipe written for the classic client; upgrading to a boto3 version that introduced preferred_transfer_client and not pruning the config.","solutions":["Remove or leave at default every TransferConfig attribute not in the allowed CRT set (multipart_threshold, max_concurrency, max_request_concurrency, multipart_chunksize, preferred_transfer_client).","If you need classic-client-only tuning (use_threads, max_bandwidth), set preferred_transfer_client back to its default (the classic botocore manager) instead of 'crt'.","Inspect the error message's invalid_crt_args list and delete exactly those kwargs from your TransferConfig constructor."],"exampleFix":"// before\nconfig = TransferConfig(\n    preferred_transfer_client='crt',\n    use_threads=True,\n    max_bandwidth=8_000_000,\n)\n// after\nconfig = TransferConfig(\n    preferred_transfer_client='crt',\n    multipart_threshold=8 * 1024 * 1024,\n    max_concurrency=10,\n)","handlingStrategy":"validation","validationCode":"ALLOWED = {\n    'multipart_threshold', 'max_concurrency',\n    'max_request_concurrency', 'multipart_chunksize',\n    'preferred_transfer_client',\n}\nprovided = {k: v for k, v in vars(config).items() if v is not None}\nbad = [k for k in provided if k not in ALLOWED]\nassert not bad, f'Invalid CRT transfer options: {bad}'","typeGuard":"def is_crt_compatible_config(cfg) -> bool:\n    allowed = {'multipart_threshold', 'max_concurrency',\n              'max_request_concurrency', 'multipart_chunksize',\n              'preferred_transfer_client'}\n    return all(k in allowed or getattr(cfg, k, None) is None\n               for k in dir(cfg) if not k.startswith('_'))","tryCatchPattern":"from boto3.exceptions import InvalidCrtTransferConfigError\ntry:\n    s3.upload_file(src, bucket, key, Config=config)\nexcept InvalidCrtTransferConfigError as e:\n    bad = [s for s in str(e).split(':', 1)[1].split('`')[0].split(',') if s.strip()]\n    for k in bad:\n        setattr(config, k.strip(), None)  # reset and retry with classic client","preventionTips":["Keep a single TransferConfig factory that branches on preferred_transfer_client.","Document which TransferConfig fields each transfer client supports.","Unit-test config construction against _ALLOWED_CRT_TRANSFER_CONFIG_OPTIONS."],"tags":["s3","crt","transfer","config","boto3"],"backgroundTag":null,"analyzedSha":"6e10b029c1326a437932a8b24f38af69fd986e15","analyzedAt":"2026-08-11T20:52:47.213Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}