> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tensor9.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS Rust SDK Guide

> Configure AWS SDK for Rust to call a Cloud Adapter endpoint and classify SDK failures.

AWS SDK for Rust endpoint APIs evolve with the SDK. Pin the crate versions you test, compile the example with those versions, and keep endpoint construction in one module.

## Choose how to set the endpoint

### Set it for the process

```bash theme={null}
export AWS_ENDPOINT_URL_S3="https://adapter.example.test"
```

AWS SDK for Rust reads that service-specific setting while loading shared configuration:

```rust theme={null}
use aws_config::BehaviorVersion;
use aws_sdk_s3::Client;

let shared = aws_config::defaults(BehaviorVersion::latest())
    .region("us-east-1")
    .load()
    .await;

let service = aws_sdk_s3::config::Builder::from(&shared)
    .force_path_style(true)
    .build();
let client = Client::from_conf(service);
```

### Set it on one client

```bash theme={null}
export T9_CLOUD_ADAPTER_ENDPOINT="https://adapter.example.test"
```

```rust theme={null}
use aws_config::BehaviorVersion;
use aws_sdk_s3::Client;

async fn adapter_client() -> Client {
    let shared = aws_config::defaults(BehaviorVersion::latest())
        .region("us-east-1")
        .load()
        .await;

    let service = aws_sdk_s3::config::Builder::from(&shared)
        .endpoint_url(std::env::var("T9_CLOUD_ADAPTER_ENDPOINT").expect("T9_CLOUD_ADAPTER_ENDPOINT"))
        .force_path_style(true)
        .build();

    Client::from_conf(service)
}
```

The standard AWS credential chain supplies origin-side authentication. Target-cloud credentials remain with Cloud Adapter and do not belong in the Rust process.

An explicit `endpoint_url` takes precedence over `AWS_ENDPOINT_URL_S3`.

## Verify object bytes

```rust theme={null}
use aws_sdk_s3::primitives::ByteStream;

let client = adapter_client().await;
let bucket = std::env::var("TEST_BUCKET")?;
let key = format!("rust/{}-hello.txt", std::time::SystemTime::now()
    .duration_since(std::time::UNIX_EPOCH)?.as_millis());
let expected = b"hello through Cloud Adapter\n".to_vec();

client.put_object()
    .bucket(&bucket)
    .key(&key)
    .content_type("text/plain")
    .body(ByteStream::from(expected.clone()))
    .send().await?;

client.head_object().bucket(&bucket).key(&key).send().await?;

let response = client.get_object().bucket(&bucket).key(&key).send().await?;
let actual = response.body.collect().await?.into_bytes();
assert_eq!(actual.as_ref(), expected.as_slice());

client.delete_object().bucket(&bucket).key(&key).send().await?;
```

Use an async runtime such as Tokio and bound the overall operation with a timeout appropriate to the workload. Avoid collecting unbounded production objects into memory.

## Classify failures

The SDK returns `SdkError`, which distinguishes construction, timeout, dispatch, response, and service errors. Preserve that classification. When a service response exists, record the modeled error code and request metadata. When it does not, debug DNS, TLS, routing, or timeout behavior before blaming translation.

## Production checklist

* Pin and test `aws-config`, `aws-sdk-s3`, and runtime versions together.
* Reuse the client and HTTP connector.
* Keep endpoint, region, and addressing mode explicit.
* Verify native target state after mutations.
* Add an expected missing-key request.
* Test pagination, multipart upload, ranges, and conditionals only if your application uses them.
* Check each operation against the [S3 service page](/cloud-adapter/service-catalog/aws/databases-storage/s3).

See [response headers](/cloud-adapter/debugging/response-headers) and [Testing Your Adapters](/cloud-adapter/local-testing/testing-your-adapters) for evidence to retain.
