- S3Mock
- Quick Start
- Changelog
- Version Compatibility
- Migration Guides
- Supported S3 Operations
- Usage
- Configuration
- Important Limitations
- Troubleshooting
- File System Structure
- Performance & Resources
- Architecture & Development
- Build & Run
- Contributing
- License
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.jacksonpackages) - AWS SDK v1 removed: All v1 client support has been dropped
- JUnit 4 removed: The
s3mock-junit4module no longer exists - Controller package moved:
com.adobe.testing.s3mocktocom.adobe.testing.s3mock.controller - Legacy properties removed: Old-style configuration properties have been removed
- Apache Commons removed:
commons-compress,commons-codec,commons-lang3replaced 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)
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, nothttp://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) and9191(HTTPS) must be free - Check with:
lsof -i :9090(macOS/Linux) ornetstat -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-sslflag - cURL: Add
--insecureflag - 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=trueonly 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
Module Documentation:
- Project Overview - Architecture, code style, DO/DON'T guardrails
- Server Module - Core implementation (Controller→Service→Store layers)
- Integration Tests - Testing with AWS SDK v2 clients
- Test Support - Testcontainers, JUnit 5, TestNG integrations
Build & Run
Requirements: Java 25, Maven 3.9+, Docker (for Docker build and integration tests)
Build:
make install # Full build with Docker make skip-docker # Skip Docker build
Run from source:
make run # As Spring Boot application # As Docker container ./mvnw clean package -pl server -am -DskipTests docker run -p 9090:9090 -p 9191:9191 adobe/s3mock:latest
Run integration tests:
Technology:
- S3Mock uses Kotlin 2.3+ (language/API compatibility: 2.2) and Spring Boot 4.0
- Tests use Kotlin
- JVM bytecode target: 17; building and running from source requires JDK 25 (per Spring Boot 4.x guidance), while the packaged artifacts run on Java 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.