Skip to content
/ S3Mock Public

A mock implementation of the AWS S3 API startable as Docker image, TestContainer, JUnit 4 rule, JUnit Jupiter extension or TestNG listener

License

Notifications You must be signed in to change notification settings

adobe/S3Mock

Latest Version Maven Build Docker Hub Docker Pulls Kotlin JVM OpenSSF Best Practices OpenSSF Scorecard GitHub stars

S3Mock

S3Mock is a lightweight server implementing parts of the Amazon S3 API for local integration testing. It eliminates the need for actual AWS infrastructure during development and testing.

Recommended usage: Run S3Mock as a Docker container or with Testcontainers to avoid classpath conflicts.

Quick Start

Get up and running in 30 seconds:

# 1. Start S3Mock
docker run -p 9090:9090 adobe/s3mock

# 2. Create a bucket
aws s3api create-bucket --bucket my-bucket --endpoint-url http://localhost:9090

# 3. Upload a file
aws s3api put-object --bucket my-bucket --key my-file --body ./my-file --endpoint-url http://localhost:9090

# 4. Download the file
aws s3api get-object --bucket my-bucket --key my-file --endpoint-url http://localhost:9090 output-file

For programmatic testing, see Testcontainers or JUnit 5 Extension below.

Changelog

Version Compatibility

S3Mock Status Spring Boot Kotlin Java (target) Java (compile) AWS SDK v2 Testcontainers
5.x Active 4.0.x 2.3 17 25 2.x 2.x
4.x Deprecated 3.x 2.1-2.2 17 17 2.x 1.x
3.x Deprecated 2.x 1.x-2.0 17 17 2.x 1.x
2.x End of Life 2.x - 11 11 1.x/2.x -

Migration Guides

4.x to 5.x (Current)

  • Jackson 3: XML annotations updated to Jackson 3 (tools.jackson packages)
  • AWS SDK v1 removed: All v1 client support has been dropped
  • JUnit 4 removed: The s3mock-junit4 module no longer exists
  • Controller package moved: com.adobe.testing.s3mock to com.adobe.testing.s3mock.controller
  • Legacy properties removed: Old-style configuration properties have been removed
  • Apache Commons removed: commons-compress, commons-codec, commons-lang3 replaced by Kotlin/Java stdlib
  • Owner DisplayName removed: AWS APIs stopped returning DisplayName - this is a file system breaking change for existing data

3.x to 4.x

  • Tomcat replaces Jetty: Application container changed from Jetty to Tomcat
  • Versioning API: Basic support for S3 versioning added
  • If-(Un)modified-Since: Conditional request handling implemented

For full details, see the Changelog.

Supported S3 Operations

See the complete operations table in AWS documentation.

Click to expand operations table (operations marked ✅ are supported)
Operation Support Comment
AbortMultipartUpload
CompleteMultipartUpload
CopyObject
CreateBucket
CreateMultipartUpload
DeleteBucket
DeleteBucketAnalyticsConfiguration
DeleteBucketCors
DeleteBucketEncryption
DeleteBucketIntelligentTieringConfiguration
DeleteBucketInventoryConfiguration
DeleteBucketLifecycle
DeleteBucketMetricsConfiguration
DeleteBucketOwnershipControls
DeleteBucketPolicy
DeleteBucketReplication
DeleteBucketTagging
DeleteBucketWebsite
DeleteObject
DeleteObjects
DeleteObjectTagging
DeletePublicAccessBlock
GetBucketAccelerateConfiguration
GetBucketAcl
GetBucketAnalyticsConfiguration
GetBucketCors
GetBucketEncryption
GetBucketIntelligentTieringConfiguration
GetBucketInventoryConfiguration
GetBucketLifecycle Deprecated in S3 API
GetBucketLifecycleConfiguration
GetBucketLocation
GetBucketLogging
GetBucketMetricsConfiguration
GetBucketNotification
GetBucketNotificationConfiguration
GetBucketOwnershipControls
GetBucketPolicy
GetBucketPolicyStatus
GetBucketReplication
GetBucketRequestPayment
GetBucketTagging
GetBucketVersioning
GetBucketWebsite
GetObject
GetObjectAcl
GetObjectAttributes for objects, not parts
GetObjectLegalHold
GetObjectLockConfiguration
GetObjectRetention
GetObjectTagging
GetObjectTorrent
GetPublicAccessBlock
HeadBucket
HeadObject
ListBucketAnalyticsConfigurations
ListBucketIntelligentTieringConfigurations
ListBucketInventoryConfigurations
ListBucketMetricsConfigurations
ListBuckets
ListMultipartUploads
ListObjects Deprecated in S3 API
ListObjectsV2
ListObjectVersions
ListParts
PostObject
PutBucketAccelerateConfiguration
PutBucketAcl
PutBucketAnalyticsConfiguration
PutBucketCors
PutBucketEncryption
PutBucketIntelligentTieringConfiguration
PutBucketInventoryConfiguration
PutBucketLifecycle Deprecated in S3 API
PutBucketLifecycleConfiguration
PutBucketLogging
PutBucketMetricsConfiguration
PutBucketNotification
PutBucketNotificationConfiguration
PutBucketOwnershipControls
PutBucketPolicy
PutBucketReplication
PutBucketRequestPayment
PutBucketTagging
PutBucketVersioning
PutBucketWebsite
PutObject
PutObjectAcl
PutObjectLegalHold
PutObjectLockConfiguration
PutObjectRetention
PutObjectTagging
PutPublicAccessBlock
RestoreObject
SelectObjectContent
UploadPart
UploadPartCopy
WriteGetObjectResponse

Usage

Docker (Recommended)

The Docker image is available on Docker Hub and is the recommended way to run S3Mock.

Basic usage:

docker run -p 9090:9090 -p 9191:9191 adobe/s3mock

Ports: 9090 (HTTP), 9191 (HTTPS)

With configuration:

docker run -p 9090:9090 -p 9191:9191 \
  -e COM_ADOBE_TESTING_S3MOCK_STORE_INITIAL_BUCKETS=test-bucket \
  -e debug=true \
  adobe/s3mock

Docker Compose:

services:
  s3mock:
    image: adobe/s3mock:latest
    environment:
      - COM_ADOBE_TESTING_S3MOCK_STORE_INITIAL_BUCKETS=bucket1,bucket2
    ports:
      - 9090:9090
      - 9191:9191

With persistent storage:

services:
  s3mock:
    image: adobe/s3mock:latest
    environment:
      - COM_ADOBE_TESTING_S3MOCK_STORE_ROOT=containers3root
      - COM_ADOBE_TESTING_S3MOCK_STORE_RETAIN_FILES_ON_EXIT=true
    ports:
      - 9090:9090
    volumes:
      - ./locals3root:/containers3root

Testcontainers

The S3MockContainer provides a pre-configured Testcontainers implementation.

Maven dependency:

<dependency>
  <groupId>com.adobe.testing</groupId>
  <artifactId>s3mock-testcontainers</artifactId>
  <version>...</version>
  <scope>test</scope>
</dependency>

Usage example:

@Testcontainers
class MyTest {
  @Container
  val s3Mock = S3MockContainer("latest")
    .withInitialBuckets("test-bucket")

  @Test
  fun test() {
    val s3Client = S3Client.builder()
      .endpointOverride(URI.create(s3Mock.httpEndpoint))
      .region(Region.US_EAST_1)
      .credentialsProvider(StaticCredentialsProvider.create(
        AwsBasicCredentials.create("foo", "bar")
      ))
      .build()

    s3Client.createBucket { it.bucket("my-bucket") }
  }
}

JUnit 5 Extension

Note: This module may be removed in S3Mock 6.x. Consider using Testcontainers instead.

Maven dependency:

<dependency>
  <groupId>com.adobe.testing</groupId>
  <artifactId>s3mock-junit5</artifactId>
  <version>...</version>
  <scope>test</scope>
</dependency>

Usage:

@ExtendWith(S3MockExtension::class)
class MyTest {
  @Test
  fun test(s3Client: S3Client) {
    s3Client.createBucket { it.bucket("test-bucket") }
  }
}

See examples: Declarative | Programmatic

TestNG Listener

Note: This module may be removed in S3Mock 6.x. Consider using Testcontainers instead.

Maven dependency:

<dependency>
  <groupId>com.adobe.testing</groupId>
  <artifactId>s3mock-testng</artifactId>
  <version>...</version>
  <scope>test</scope>
</dependency>

Configure in testng.xml - see example configuration.

AWS CLI

Use with --endpoint-url and --no-verify-ssl (for HTTPS):

# Create bucket
aws s3api create-bucket --bucket my-bucket --endpoint-url http://localhost:9090

# Upload object
aws s3api put-object --bucket my-bucket --key my-file --body ./my-file --endpoint-url http://localhost:9090

# Download object
aws s3api get-object --bucket my-bucket --key my-file --endpoint-url http://localhost:9090 output-file

# HTTPS
aws s3api get-object --bucket my-bucket --key my-file --no-verify-ssl --endpoint-url https://localhost:9191 output-file

cURL

# Create bucket
curl -X PUT http://localhost:9090/my-bucket/

# Upload object
curl -X PUT --upload-file ./my-file http://localhost:9090/my-bucket/my-file

# Download object
curl http://localhost:9090/my-bucket/my-file -O

# HTTPS (with self-signed certificate)
curl --insecure https://localhost:9191/my-bucket/my-file -O

Configuration

Configure S3Mock using environment variables:

Variable Default Description
COM_ADOBE_TESTING_S3MOCK_STORE_ROOT Java temp directory Base directory for file storage
COM_ADOBE_TESTING_S3MOCK_STORE_REGION us-east-1 AWS region to mock
COM_ADOBE_TESTING_S3MOCK_STORE_INITIAL_BUCKETS none Comma-separated list of buckets to create on startup
COM_ADOBE_TESTING_S3MOCK_STORE_RETAIN_FILES_ON_EXIT false Keep files after shutdown
COM_ADOBE_TESTING_S3MOCK_STORE_VALID_KMS_KEYS none Comma-separated KMS key ARNs (validation only, no encryption)
COM_ADOBE_TESTING_S3MOCK_CONTROLLER_CONTEXT_PATH "" Base context path for all endpoints
debug false Enable Spring Boot debug logging
trace false Enable Spring Boot trace logging

Important Limitations

  • Path-style access only: S3Mock supports http://localhost:9090/bucket/key, not http://bucket.localhost:9090/key
  • Presigned URLs: Accepted but not validated (expiration, signature, HTTP verb not checked)
  • Self-signed SSL: Included certificate requires clients to trust it or ignore SSL errors
  • KMS: Key validation only - no actual encryption performed
  • Not for production: S3Mock is a testing tool and lacks security features required for production use

Troubleshooting

Click to expand troubleshooting guide

Port already in use (Address already in use)

  • Ports 9090 (HTTP) and 9191 (HTTPS) must be free
  • Check with: lsof -i :9090 (macOS/Linux) or netstat -ano | findstr :9090 (Windows)
  • Stop conflicting processes or map to different ports: docker run -p 9091:9090 adobe/s3mock

Connection refused

  • Verify S3Mock is running: docker ps | grep s3mock
  • Ensure you're using the correct endpoint URL (e.g., http://localhost:9090)
  • Wait for startup to complete — check logs with docker logs <container-id>

SSL certificate errors

  • S3Mock uses a self-signed certificate on the HTTPS port (9191)
  • AWS CLI: Add --no-verify-ssl flag
  • cURL: Add --insecure flag
  • Java/Kotlin: Configure the SDK to trust the S3Mock certificate or disable SSL verification

Docker not running (Testcontainers)

  • Testcontainers and integration tests require a running Docker daemon
  • Start Docker Desktop or the Docker service before running tests
  • Check with: docker info

Classpath conflicts (JUnit 5 Extension / embedded mode)

  • S3Mock's embedded Spring Boot server may conflict with your application's dependencies
  • Recommended: Use Testcontainers or Docker instead to run S3Mock in isolation
  • If using embedded mode, ensure compatible Spring Boot versions

AWS SDK endpoint configuration

  • AWS SDK v2: Use .endpointOverride(URI.create("http://localhost:9090"))
  • Credentials: Use any dummy credentials (e.g., AwsBasicCredentials.create("foo", "bar"))
  • Region: Use any region (S3Mock defaults to us-east-1)

Objects not found / wrong bucket

  • S3Mock supports path-style access only: http://localhost:9090/bucket/key
  • Virtual-hosted style (http://bucket.localhost:9090/key) is not supported
  • Verify your SDK client is configured for path-style access

File System Structure

S3Mock stores data on disk with the following structure:

<root>/
  <bucket-name>/
    bucketMetadata.json              # Bucket metadata
    <object-uuid>/
      binaryData                     # Object content
      objectMetadata.json            # Object metadata
      <version-id>-binaryData        # Versioned object (if versioning enabled)
      <version-id>-objectMetadata.json
    multiparts/
      <upload-id>/
        multipartMetadata.json
        <part-number>.part

Note: The file system structure is an implementation detail and may change between releases. While files can be inspected during runtime, reusing persisted data across restarts is not officially supported.

Performance & Resources

S3Mock is designed for testing, not production workloads. Keep the following in mind:

  • Disk: All objects are stored on the local filesystem — disk usage grows with stored data
  • Memory: Scales with concurrent multipart uploads and in-flight requests
  • CI environments: Consider setting Docker resource limits (e.g., --memory=512m) to avoid contention with other services
  • Cleanup: By default, S3Mock deletes all stored data on shutdown. Use RETAIN_FILES_ON_EXIT=true only when needed

Architecture & Development

graph LR
    Client["AWS SDK / CLI / cURL"] -->|HTTP :9090 / HTTPS :9191| Controller
    subgraph S3Mock
        Controller["Controller<br/>(REST endpoints)"] -->|delegates| Service["Service<br/>(business logic)"]
        Service -->|coordinates| Store["Store<br/>(persistence)"]
        Store -->|read/write| FS["Filesystem"]
    end
Loading

Module Documentation:

Build & Run

Requirements: Java 17+, Maven 3.9+, Docker (for Docker build and integration tests)

Build:

# Full build with Docker
./mvnw clean install

# Skip Docker build
./mvnw clean install -DskipDocker

Run from source:

# As Spring Boot application
./mvnw spring-boot:run -pl server

# As Docker container
./mvnw clean package -pl server -am -DskipTests
docker run -p 9090:9090 -p 9191:9191 adobe/s3mock:latest

Run integration tests:

./mvnw verify -pl integration-tests

Technology:

  • Built with Kotlin 2.3.0 and Spring Boot 4.0
  • Tests written in Kotlin
  • Target JVM: 17

Contributing

Contributions are welcome! See Contributing Guide.

Governance: Project leads make final decisions - see developers in pom.xml.

Security: See Security Policy for reporting vulnerabilities. S3Mock uses GitHub Actions for SBOM and vulnerability scanning.

License

Licensed under the Apache License 2.0 - see LICENSE.


IntelliJ IDEA

Star History

About

A mock implementation of the AWS S3 API startable as Docker image, TestContainer, JUnit 4 rule, JUnit Jupiter extension or TestNG listener

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Languages