> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.zata.prathamchopde.site/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.zata.prathamchopde.site/_mcp/server.

# Java

The AWS SDK for Java 2.x works with Zata. Point the S3 client at the Zata endpoint, and you can use the normal S3 calls from Java, including Spring Boot apps.

> **Info**
>
> Tested with the AWS SDK for Java 2.46.7 (`software.amazon.awssdk:s3`) on Java 21 on Zata in October 2026.

## Before you start

* A bucket. See [Create a bucket](/buckets/create-a-bucket).
* An access key and secret key from the same region as the bucket. See [Access keys](/access/access-keys).

## Connection settings

| Setting                                                     | Value                                                                                         |
| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `endpointOverride`                                          | `https://idr01.zata.ai` for Indore, `https://bom01.zata.ai` for Mumbai                        |
| `region`                                                    | `Region.US_EAST_1`                                                                            |
| Access key / Secret key                                     | from **Access Keys** in the Zata console. The key must be from the same region as the bucket. |
| `forcePathStyle`                                            | `true`                                                                                        |
| `requestChecksumCalculation` / `responseChecksumValidation` | `WHEN_REQUIRED`                                                                               |

## Add the SDK

#### Maven

```xml
<dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>s3</artifactId>
  <version>2.46.7</version>
</dependency>
```

#### Gradle

```kotlin
implementation("software.amazon.awssdk:s3:2.46.7")
```

## Create the client

Keep your keys out of the code. Put them in environment variables; the SDK reads them by itself:

```bash
export AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY
export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
```

Then create the client. For a bucket in Mumbai, use `https://bom01.zata.ai`.

```java
import java.net.URI;
import software.amazon.awssdk.core.checksums.RequestChecksumCalculation;
import software.amazon.awssdk.core.checksums.ResponseChecksumValidation;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;

S3Client s3 = S3Client.builder()
    .endpointOverride(URI.create("https://idr01.zata.ai"))
    .region(Region.US_EAST_1)
    .forcePathStyle(true)
    .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED)
    .responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED)
    .build();
```

> **Warning**
>
> The two `WHEN_REQUIRED` lines are required. With the SDK's default settings (version 2.30 and newer), **every upload to Zata fails** with `XAmzContentSHA256Mismatch`, even small files.

## Upload, download and list files

```java
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.model.*;

// Upload
s3.putObject(PutObjectRequest.builder().bucket("my-bucket").key("hello.txt").build(),
             RequestBody.fromString("hello from java"));

// Download
String text = s3.getObjectAsBytes(GetObjectRequest.builder().bucket("my-bucket").key("hello.txt").build())
                .asUtf8String();

// Count the files in the bucket
int count = s3.listObjectsV2(ListObjectsV2Request.builder().bucket("my-bucket").build()).keyCount();
```

To upload a file from disk, use `RequestBody.fromFile(Paths.get("myfile.txt"))` (with `import java.nio.file.Paths;`).

## List your buckets

```java
s3.listBuckets().buckets().forEach(b -> System.out.println(b.name()));
```

A sub-user's key gets an empty list here, even for buckets it can use. Use the bucket name directly.

## Make a download link

A presigned URL lets someone download one file without keys, until the link expires.

```java
import java.time.Duration;
import software.amazon.awssdk.services.s3.S3Configuration;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;

try (S3Presigner presigner = S3Presigner.builder()
        .endpointOverride(URI.create("https://idr01.zata.ai"))
        .region(Region.US_EAST_1)
        .serviceConfiguration(S3Configuration.builder().pathStyleAccessEnabled(true).build())
        .build()) {
    String url = presigner.presignGetObject(GetObjectPresignRequest.builder()
            .signatureDuration(Duration.ofMinutes(10))
            .getObjectRequest(GetObjectRequest.builder().bucket("my-bucket").key("hello.txt").build())
            .build()).url().toString();
}
```

Anyone who has the link can use it until it expires, so share it only with the intended person.

## Troubleshooting

| Problem                                     | Fix                                                                                                                                                                                      |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `XAmzContentSHA256Mismatch` on every upload | Add the two `WHEN_REQUIRED` lines to the client. Or set the environment variables `AWS_REQUEST_CHECKSUM_CALCULATION=when_required` and `AWS_RESPONSE_CHECKSUM_VALIDATION=when_required`. |
| `InvalidAccessKeyId`                        | `endpointOverride` is missing (requests go to AWS), or the key is from the other region.                                                                                                 |
| `NoSuchBucket`                              | Use the endpoint of the region the bucket is in.                                                                                                                                         |
| The bucket list is empty                    | A sub-user's key cannot list buckets. Use the bucket name directly.                                                                                                                      |

For other errors, see [Large uploads](/help/troubleshooting/large-uploads) and [Wrong endpoint or region](/help/troubleshooting/endpoint-and-region).