- 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 that implements a subset of the Amazon S3 API for local integration testing. It removes the need for real AWS infrastructure during development and testing.
Recommended usage: Run S3Mock as a Docker container or via Testcontainers to avoid classpath conflicts.
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-fileFor programmatic testing, see Testcontainers or JUnit 5 Extension below.
| 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 | End of Life | 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 | - |
| 1.x | End of Life | 2.x | - | 11 | 11 | 1.x/2.x | - |
- Filesystem changes: The internal file structure changed; existing data may be incompatible with the new version.
- Jackson 3: XML annotations migrated to Jackson 3 (
tools.jacksonpackages) - AWS SDK v1 removed: All v1 client support dropped
- JUnit 4 removed: The
s3mock-junit4module has been removed - Controller package moved:
com.adobe.testing.s3mock→com.adobe.testing.s3mock.controller - Legacy environment variables removed: Replaced by new environment variables — see Configuration.
- Legacy properties removed: Replaced by new configuration properties — see Configuration.
- Apache Commons removed:
commons-compress,commons-codec,commons-lang3replaced by Kotlin/Java stdlib - Owner DisplayName removed: AWS APIs no longer return
DisplayName— this is a breaking change for persisted data
- Tomcat replaces Jetty: Embedded container switched from Jetty to Tomcat
- Versioning API: Basic S3 versioning support added
- If-(Un)modified-Since: Conditional request handling added
For full details, see the Changelog.
See the complete operations table in the AWS documentation.
Click to expand operations table (operations marked ✅ are supported)
Available on Docker Hub, the Docker image is the recommended way to run S3Mock.
Basic usage:
docker run -p 9090:9090 -p 9191:9191 adobe/s3mockPorts: 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 SPRING_PROFILES_ACTIVE=debug \
adobe/s3mockDocker Compose:
services:
s3mock:
image: adobe/s3mock:latest
environment:
- COM_ADOBE_TESTING_S3MOCK_STORE_INITIAL_BUCKETS=bucket1,bucket2
ports:
- 9090:9090
- 9191:9191With 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:/containers3rootThe S3MockContainer provides a ready-to-use 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") }
}
}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
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.
Pass --endpoint-url to point the CLI at S3Mock, and add --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# 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 -OConfigure 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 |
Activate profiles via the SPRING_PROFILES_ACTIVE environment variable:
| Profile | Description |
|---|---|
debug |
Debug-level logging for Spring Web, Apache, and request details. Also activates actuator. |
trace |
Trace-level logging for Spring Web, Apache, and request details. Also activates actuator. |
actuator |
Enables JMX and all Spring Boot Actuator endpoints (health, info, etc.). |
Actuator endpoints are disabled by default. To enable them:
# Via debug or trace profile (also enables verbose logging)
docker run -p 9090:9090 -p 9191:9191 -e SPRING_PROFILES_ACTIVE=debug adobe/s3mock
# Via actuator profile only (no extra logging)
docker run -p 9090:9090 -p 9191:9191 -e SPRING_PROFILES_ACTIVE=actuator adobe/s3mock
# Via individual environment variables (without any profile)
docker run -p 9090:9090 -p 9191:9191 \
-e MANAGEMENT_ENDPOINTS_ACCESS_DEFAULT=unrestricted \
-e MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE='*' \
adobe/s3mockS3Mock exposes two readiness endpoints:
/favicon.ico (always available)
Returns HTTP 200 OK with an empty body. This endpoint is always active, requires no configuration, and is used by Testcontainers and the integration test suite to detect readiness:
curl -sf http://localhost:9090/favicon.ico/actuator/health (requires actuator profile)
The standard Spring Boot health endpoint. Only available when the actuator profile (or debug/trace) is active:
# Start with actuator enabled
docker run -p 9090:9090 -p 9191:9191 -e SPRING_PROFILES_ACTIVE=actuator adobe/s3mock
# Check health
curl -sf http://localhost:9090/actuator/healthDocker Compose health check example:
services:
s3mock:
image: adobe/s3mock:latest
ports:
- 9090:9090
- 9191:9191
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:9090/favicon.ico"]
interval: 5s
retries: 3- 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: The bundled certificate requires clients to trust it or disable SSL verification
- KMS: Key ARNs are validated, but no actual encryption is performed
- Not for production: S3Mock is a testing tool and lacks the security features required for production use
Click to expand troubleshooting guide
Port already in use (Address already in use)
- Ports
9090(HTTP) and9191(HTTPS) must be available - 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 with
curl -sf http://localhost:9090/favicon.icoor check logs withdocker 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: Supply any dummy credentials (e.g.,
AwsBasicCredentials.create("foo", "bar")) - Region: Specify 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
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.
S3Mock is designed for testing, not production workloads:
- Disk: All objects are stored on the local filesystem — disk usage grows proportionally with stored data
- Memory: Consumption 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. Set
COM_ADOBE_TESTING_S3MOCK_STORE_RETAIN_FILES_ON_EXIT=trueonly when you need data to survive restarts
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
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 buildRun 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:latestRun integration tests:
make integration-testsTechnology:
- S3Mock is written in Kotlin 2.3+ (language/API compatibility: 2.2) with Spring Boot 4.0
- All tests are written in 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+.
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 generation and vulnerability scanning.
Licensed under the Apache License 2.0 - see LICENSE.