boto/boto3 · error · MissingDependencyException

CRT transfer client is configured but is missing minimum…

Error message

CRT transfer client is configured but is missing minimum crt version. CRT installed: {HAS_CRT}

What it means

Raised by `_should_use_crt` when `TransferConfig.preferred_transfer_client` is set to `'crt'` but the optional `awscrt` package is either not installed or older than the required minimum (`0.19.18`). The CRT (AWS Common Runtime) transfer client is an optimized, optional backend for S3 transfers; boto3 falls back to the default manager only when the client is not explicitly requested. Raising as `MissingDependencyException` makes the absent optional dependency explicit.

Solutions

  1. Install or upgrade the CRT dependency: `pip install -U 'awscrt>=0.19.18'`.
  2. If you do not actually need CRT, remove `preferred_transfer_client='crt'` from your TransferConfig so boto3 uses the default transfer manager.
  3. Set `preferred_transfer_client='auto'` to let boto3 use CRT only when available and beneficial.
  4. On platforms where `awscrt` has no wheel, build it from source (`pip install awscrt --no-binary :all:`) only if build toolchain is present; otherwise stay on the default client.

Example fix

# before
from boto3.s3.transfer import TransferConfig
cfg = TransferConfig(preferred_transfer_client='crt')
s3.download_file('b', 'k', '/tmp/k')  # MissingDependencyException if awscrt absent/old

# after (option A: install the dependency)
#   pip install -U 'awscrt>=0.19.18'
# after (option B: drop the requirement)
cfg = TransferConfig()  # default manager, no CRT needed
Defensive patterns

Strategy: validation

Validate before calling

try:
    import awscrt
    from packaging.version import Version
    assert Version(awscrt.__version__) >= Version('0.19.18'), 'awscrt too old'
    HAS_MIN_CRT = True
except ImportError:
    HAS_MIN_CRT = False

from boto3.s3.transfer import TransferConfig
cfg = TransferConfig(preferred_transfer_client='crt') if HAS_MIN_CRT else TransferConfig()

Type guard

def crt_available(min_version=(0, 19, 18)) -> bool:
    try:
        import awscrt
        parts = tuple(int(x) for x in awscrt.__version__.split('.')[:3])
        return parts >= min_version
    except Exception:
        return False

Try / catch

from boto3.exceptions import MissingDependencyException
try:
    s3.download_file(b, k, path, Config=TransferConfig(preferred_transfer_client='crt'))
except MissingDependencyException:
    s3.download_file(b, k, path)  # fall back to default transfer client

Prevention

When it happens

Trigger: Constructing `S3Transfer`/`TransferConfig` with `preferred_transfer_client='crt'` (the constant `CRT_TRANSFER_CLIENT`) while `awscrt` is missing or `awscrt.__version__ < 0.19.18`. Triggered when the first transfer that evaluates the config is created.

Common situations: Enabling the CRT client after reading a performance guide but forgetting `pip install awscrt`; an environment where `awscrt` failed to install (platform/arch mismatch, e.g. some musl/older-glibc images); pinning an old `awscrt` from a lockfile; CI cache restoring a stale `awscrt`.

Related errors


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

Appendix: source

Thrown at boto3/s3/transfer.py:209


def _should_use_crt(config):
    # This feature requires awscrt>=0.19.18
    has_min_crt = HAS_CRT and has_minimum_crt_version((0, 19, 18))
    is_optimized_instance = has_min_crt and awscrt.s3.is_optimized_for_system()
    pref_transfer_client = config.preferred_transfer_client.lower()

    if (
        pref_transfer_client == constants.CRT_TRANSFER_CLIENT
        and not has_min_crt
    ):
        msg = (
            "CRT transfer client is configured but is missing minimum CRT "
            f"version. CRT installed: {HAS_CRT}"
        )
        if HAS_CRT:
            msg += f", with version: {awscrt.__version__}"
        raise MissingDependencyException(msg=msg)

    if (
        is_optimized_instance
        and pref_transfer_client == constants.AUTO_RESOLVE_TRANSFER_CLIENT
    ) or pref_transfer_client == constants.CRT_TRANSFER_CLIENT:
        logger.debug(
            "Attempting to use CRTTransferManager. Config settings may be ignored."
        )
        return True

    logger.debug(
        "Opting out of CRT Transfer Manager. "
        "Preferred client: %s, CRT available: %s, Instance Optimized: %s",
        pref_transfer_client,
        HAS_CRT,
        is_optimized_instance,
    )
    return False

View on GitHub (pinned to 6e10b029c1)