S3 API

Alluxio exposes an S3-compatible REST API that allows applications built for Amazon S3 to read and write data without code changes. This page covers endpoint configuration, authentication, load balancing, and client compatibility.

Need low-latency writes? If your workload requires millisecond-level PUT latency or async persistence, see S3-API Write Optimization.

Prerequisites

Complete Installing on Kubernetes through Step 5 (Mount Storage) before proceeding. The S3 API requires:

  • A running Alluxio cluster (CLUSTERPHASE = Ready)

  • At least one UFS mount point — mount points become the S3 buckets exposed by the API

Quick Start

This section gets you to a working S3 endpoint in three steps using the default configuration (proxy mode, Pattern B). Most clients — including AWS CLI, boto3, and PyTorch S3 Connector — work out of the box with this setup.

Step 1: Enable the S3 API

Add the following to spec.properties in alluxio-cluster.yaml and apply:

spec:
  properties:
    alluxio.worker.s3.api.enabled: "true"
kubectl apply -f alluxio-cluster.yaml

The S3 API is exposed on every worker on port 29998 (HTTP) and 29996 (HTTPS, requires TLS).

Step 2: Expose the Endpoint

With a load balancer (recommended for production)

Add a worker service to alluxio-cluster.yaml:

Wait for the external IP to be assigned:

✅ Success: EXTERNAL-IP is populated. Use that address as <ENDPOINT> below.

Without a load balancer (eval/single-node)

Use port-forward to reach a worker directly:

Use http://localhost:29998 as <ENDPOINT>.

Step 3: Verify with AWS CLI

Configure path-style requests (required — virtual-hosted style is not supported):

With SIMPLE auth (the default), any non-empty credentials are accepted:

Quick boto3 example:

Want higher throughput? The default proxy mode traverses the cluster network twice for cross-worker reads, roughly halving throughput compared to redirect mode. If your client follows HTTP 307 redirects to non-AWS endpoints, see Pattern A for near-linear scaling.


Deployment Patterns

How It Works

Each Alluxio worker exposes an S3 endpoint on port 29998 and owns a slice of the namespace via consistent hashing. When a request lands on a worker that does not own the requested data, the worker must route it to the data owner. There are two strategies:

circle-info

Background: what HTTP 307 means here. HTTP 307 is a redirect status code — the server responds with a new URL instead of data. The client then opens a fresh connection directly to that URL. Critically, no data payload traverses the original worker: the redirect response is a tiny HTTP message, and the full read happens worker-to-client without a proxy intermediary. The only cost is one extra round-trip for the redirect itself.

  • Proxy mode (alluxio.worker.s3.redirect.enabled=false, the default): the receiving worker fetches data from the owning worker and streams it to the client. Every client works. Cost: cross-worker reads traverse the network twice (~50% throughput vs. redirect mode).

  • Redirect mode (alluxio.worker.s3.redirect.enabled=true): the receiving worker issues an HTTP 307 pointing the client directly at the data owner — zero proxy overhead, linear throughput scaling. Constraint: the AWS SDK does not follow 307 redirects to non-AWS endpoints. Clients built on it (AWS CLI, boto3, PyTorch S3 Connector) cannot use this mode.

Choosing a Pattern

Pattern A: Load Balancer + Redirect

Best for: COSBench, minio-py, and any client that correctly follows HTTP 307 redirects to non-AWS endpoints.

How it works: the load balancer distributes incoming requests across workers. With alluxio.worker.s3.redirect.enabled=true, the receiving worker checks ownership via consistent hashing and issues a 307 only when needed — if the request already lands on the data owner, no redirect occurs. The client connects directly to the data-owning worker — zero-copy, no proxy overhead. Read throughput scales linearly with the number of workers. For throughput baselines, see Benchmarking S3 API Performance.

Wait for the NLB to be provisioned (typically 1–2 minutes on AWS):

✅ Success: EXTERNAL-IP is populated. Use that hostname as the S3 endpoint.

Pattern B: Load Balancer + Proxy Mode

Best for: AWS SDK (AWS CLI), boto3, PyTorch S3 Connector (AWS CRT), and MinIO Warp — clients that do not follow HTTP 307 redirects to non-AWS endpoints.

alluxio.worker.s3.redirect.enabled=false (the default). All clients work without code changes.

Use the same load balancer setup as Pattern A, but leave alluxio.worker.s3.redirect.enabled at its default (false). The load balancer distributes requests across workers; cross-worker reads are proxied internally.

Trade-off: data traverses the cluster network twice for cross-worker reads (data owner → proxy worker → client), roughly halving aggregate throughput compared to Pattern A.

Point your S3 endpoint to the load balancer address:

circle-info

Single-worker deployments: 307 redirects only fire when the receiving worker is not the data owner. With a single worker, redirects never occur and all clients work regardless of redirect.enabled.


Authentication

Alluxio's S3 API supports two authentication methods:

SIMPLE (Default) — Alluxio parses the AWS Signature V4arrow-up-right Authorization header to extract the username, but does not validate the signature.

  • Access Key: The Alluxio username to perform operations as. If omitted, operations run as the user that launched the worker process.

  • Secret Key: Any non-empty value. Required by the client to generate the signature, but ignored by Alluxio.

OIDC — For centralized identity management using OpenID Connect tokens, refer to the Authentication guide.


Performance

Key Alluxio Parameters

The following parameters control S3 API performance. Apply the recommended values for high-throughput workloads.

  • alluxio.worker.s3.redirect.enabled — Default: false; Set to true for Pattern A (redirect mode). When false, all cross-worker reads are proxied through the receiving worker, which adds an extra network hop and roughly halves throughput. Enable only with clients that correctly follow HTTP 307 redirects to non-AWS endpoints (see Deployment Patterns).

  • alluxio.worker.s3.connection.keep.alive.enabled — Default: false; Recommended: true. Reuses TCP connections across requests to reduce handshake overhead and improve throughput under high concurrency.

  • alluxio.worker.s3.connection.idle.max.time — Default: 0sec. Idle timeout for keep-alive connections; 0 means no timeout.

  • alluxio.worker.s3.access.logging.enabled — Default: false; Recommended: true for production. When false, only failed requests are logged; when true, every request is logged. Useful for auditing and debugging; disable during benchmarks to avoid I/O overhead.

  • alluxio.worker.s3.only.https.access — Default: false. When enabled, rejects non-HTTPS requests.

  • alluxio.worker.s3.redirect.health.check.enabled — Default: true; Recommended: false for benchmarks. Disables per-request RPC health checks before redirect, reducing overhead and improving throughput; keep enabled in production for safety.

Linux Kernel Parameters

For intensive S3 benchmarks with high TCP connection rates, tuning kernel parameters can improve connection reuse and lower latency.

Parameter
Effect

net.ipv4.tcp_tw_reuse

Reuses sockets in TIME_WAIT state, preventing port exhaustion during high-frequency requests.

net.ipv4.tcp_tw_recycle

Accelerates TIME_WAIT cleanup. Removed in Linux 4.12+ — this parameter only exists on older kernels (e.g., CentOS 7 with kernel 3.10). On newer kernels, this sysctl key does not exist and the command will fail.

net.ipv4.tcp_fin_timeout

Reduces idle connection close time, freeing resources faster. Default: 60s → recommended: 30s.

Warning: Modifying kernel parameters can impact system stability. Ensure you understand these settings before applying them, especially in production environments.

NAT Compatibility: On older kernels where tcp_tw_recycle is available, enabling it may cause connection failures for clients behind a NAT device due to timestamp validation issues. Do not use in NAT environments.

Advanced Features

MultiPartUpload (MPU)

For large object uploads that pass through to the underlying storage, these parameters control multipart upload behavior:

Parameter
Default
Recommended
Description

alluxio.underfs.object.store.multipart.upload.async

false

true

Enables async multipart uploads to UFS, improving write throughput.

alluxio.underfs.s3.upload.threads.max

20

256 for high-throughput

Maximum concurrent upload threads per worker for S3 UFS writes.

alluxio.underfs.s3.multipart.upload.buffer.number

64

256 for high-throughput

Number of multipart upload buffers. Increase alongside upload.threads.max.

By default, multipart uploads are pass-through — each part is uploaded directly to the underlying storage, and the object is committed there upon CompleteMultipartUpload. Alluxio does not buffer the parts locally.

If you need to write parts to Alluxio's cache layer first and asynchronously persist them to the underlying storage, see S3-API Write Optimization.

Tagging and Metadata

  • Enable Tagging: Requires extended attribute support for your UFS:

  • Tag Limits: User-defined tags are limited to 10 per object/bucket per S3 tag restrictionsarrow-up-right. Disable with alluxio.worker.s3.tagging.restrictions.enabled=false.

  • Metadata Size: User-defined metadata is limited to 2KB per S3 metadata restrictionsarrow-up-right. Adjust with alluxio.worker.s3.header.metadata.max.size.

Limitations

Before adopting Alluxio's S3 API, be aware of these constraints:

  • Path-style only — Virtual-hosted style requests (http://<bucket>.<endpoint>/...) are not supported. All clients must use path-style (http://<endpoint>/<bucket>/<key>).

  • Buckets: Only top-level directories in the Alluxio namespace are treated as S3 buckets. The root directory (/) is not a bucket. To preserve existing S3 URIs, use the bucket name as the mount path:

  • No Versioning or Locking: If multiple clients write to the same object simultaneously, the last write wins.

  • Unsupported Characters: Object keys must not contain ?, \, ./, or ../; // may cause undefined behavior. For multipart uploads (MPU), object keys are additionally restricted to letters, digits, spaces, and the characters _ . : / = + - @ due to implementation constraints. Characters outside this set — such as &, #, %, !, ^, *, |, <, >, (, ), [, ], {, }, ", ', and ~ — are not supported in MPU object keys.

  • Folder Objects: Subdirectories are returned as 0-byte folder objects in ListObjects(V2) responses, matching AWS S3 console behavior.

  • No Atomicity: If-Match and If-None-Match headers are not supported in GetObject and PutObject.

  • Signatures are not validated — Alluxio extracts the username from the Authorization header but does not verify the cryptographic signature. The secret key can be any non-empty string.

  • AWS SDK clients must use proxy mode — AWS SDK (AWS CLI), boto3, and PyTorch S3 Connector (AWS CRT) do not follow HTTP 307 redirects to non-AWS endpoints. Use Pattern B: Load Balancer + Proxy Mode (alluxio.worker.s3.redirect.enabled=false, the default).

  • No virtual-hosted DNS — There is no DNS wildcard resolution for <bucket>.endpoint; this is a corollary of path-style only.

Supported S3 Actions

The following table lists supported S3 API actions. For detailed usage, see the official S3 API documentationarrow-up-right.

S3 API Action
Supported Headers
Supported Query Parameters

Content-Type, x-amz-copy-source, x-amz-metadata-directive, x-amz-tagging-directive, x-amz-tagging

N/A

N/A

delimiter, encoding-type, marker, max-keys, prefix

N/A

continuation-token, delimiter, encoding-type, max-keys, prefix, start-after

Content-Length, Content-MD5, Content-Type, x-amz-tagging

N/A

Content-Length, Content-MD5

N/A

Usage Examples

minio-py — Pattern A (redirect-capable)

minio-pyarrow-up-right is a Python SDK that correctly follows HTTP 307 redirects to non-AWS endpoints. Use with a load balancer endpoint.

Install with: pip install minio

boto3 — Pattern B (proxy mode)

boto3 does not follow HTTP 307 redirects to non-AWS endpoints. Use Pattern B (proxy mode) with a load balancer endpoint.

Install with: pip install boto3

PyTorch S3 Connector — Pattern B (proxy mode)

PyTorch S3 Connector is built on AWS CRT and does not follow HTTP 307 redirects to non-AWS endpoints. Use Pattern B (proxy mode) with a load balancer endpoint.

Install with:

Troubleshooting

AWS CLI, boto3, or PyTorch return errors or wrong data

Symptom: Operations fail with connection errors, or return unexpected results.

Cause: These clients are built on the AWS SDK (or AWS CRT), which does not follow HTTP 307 redirects to non-AWS endpoints. They require Pattern B: Load Balancer + Proxy Mode — see Deployment Patterns for setup instructions.

NoSuchBucket error even though the bucket exists in S3

Symptom: aws s3 ls s3://<bucket> or a GetObject returns NoSuchBucket.

Cause: In Alluxio's S3 API, buckets are Alluxio mount point names, not UFS bucket names. The bucket name in S3 requests must match the mount path in Alluxio (e.g., /s3 → bucket name s3), not the underlying S3 bucket name.

Diagnosis: List the actual bucket names Alluxio exposes:

Then use the name shown in the output — not the UFS bucket name — in subsequent requests.

Connection refused on port 29998

Symptom: aws s3 ls returns Could not connect to the endpoint URL.

Cause: The S3 API is not enabled on the workers, or the worker service is not reachable.

Fix:

  1. Confirm S3 API is enabled:

    Expected: true. If not, add alluxio.worker.s3.api.enabled: "true" to spec.properties in alluxio-cluster.yaml and apply.

  2. If running on Kubernetes without a load balancer, use port-forward:

InvalidAccessKeyId or signature errors

Cause: Alluxio's SIMPLE auth mode does not validate the signature, but the Authorization header must still be present and well-formed. Some clients omit it when no credentials are configured.

Fix: Pass any non-empty access key and secret key. With AWS CLI:

See Also

Last updated