Known limitations
MiniStack aims for AWS compatibility, but some integrations and infrastructure concepts don't translate to a single local process. This page is the honest, cross-service gap list.
If a gap blocks you, open an issue. We actively closes parity gaps — several items on this list are first-class work items, not permanent compromises. Dated against MiniStack 1.5.9.
Stored but not dispatched
These integrations accept configuration and return correct shapes, but the side-effect is not performed. Tests that assert on the stored config pass; tests that assert on downstream side-effects will not.
| Surface | What's missing |
|---|---|
| CloudWatch Alarm → Lambda / other targets | SNS alarm actions fire on state transition; Lambda and other action targets are stored but not invoked. |
| CloudWatch Metrics for Lambda | No Invocations, Errors, Duration, Throttles, ConcurrentExecutions emitted. |
| CloudWatch Metrics for SQS | ApproximateNumberOfMessagesVisible, ApproximateAgeOfOldestMessage not tracked. |
| EventBridge → API Destination retries | API destinations make real outbound HTTP calls (with OAuth refresh); AWS's 24-hour/185-attempt retry pipeline and DLQ are not modeled — a failed delivery is logged and dropped. |
| EventBridge Pipes | DynamoDB Streams → SNS and Step Functions pipes deliver (background poller); other source/target combinations are stored but not piped. |
| ECS → CloudWatch Logs (awslogs driver) | Log driver config parsed; stdout/stderr not written to log groups. |
| API Gateway access logs | AccessLogSettings stored; no log events written. |
| Step Functions logging | loggingConfiguration stored; not written to CloudWatch Logs. No ExecutionsStarted/Failed/Duration metrics. |
| CodeBuild logs | Metadata-only builds (the default) write nothing; with MINISTACK_CODEBUILD_EXECUTE=1 build output does stream to CloudWatch Logs. |
| WAFv2 rule evaluation | WebACLs, rules, IP sets all stored. Rules are not enforced against incoming requests. |
| AutoScaling policy triggers | Scaling policies + lifecycle hooks stored; never fired by CloudWatch alarms. |
| CloudFormation Stack Policy | Not implemented — SetStackPolicy / GetStackPolicy return InvalidAction; updates are never policy-gated. |
| Cognito Lambda triggers | PreTokenGeneration, the federated PreSignUp, and the CUSTOM_AUTH triggers are invoked; PostConfirmation, CustomMessage, and Pre/PostAuthentication are stored but not invoked. |
| SES identity verification | VerifyEmailIdentity / VerifyDomainIdentity jump straight to Success — no pending state, no confirmation email. |
| Route53 health checks | Checks stored; status never updated; no CloudWatch bridge. |
| S3 SSE-KMS | SSE headers validated, stored and echoed (SSE-C key checks enforced); no real cryptography — object bytes stored as sent. |
| ECS task state → EventBridge | SubmitTaskStateChange exists; event is not put on the default bus. |
Metadata-only services
These services accept and return realistic shapes so IaC tools plan and apply, but no real infrastructure is created:
- EC2 — instances, VPCs, subnets, and security groups exist as data by default (no ENI networking). Since 1.5.0,
RegisterImagecan back an instance with a real container so it is reachable andssm:SendCommandruns on it (opt-in). - CloudFront — distributions stored and returned; no edge caching or content delivery.
- Transfer Family — a real SFTP listener is bound (default port 2222, requires asyncssh); FTPS/FTP are not implemented.
- EFS — file systems, mount targets, access points stored; no POSIX filesystem or NFS mount.
- AppSync — GraphQL queries and mutations execute against DynamoDB and Lambda data sources (best-effort parser; VTL mapping templates are stored, not interpreted).
- EMR — cluster and step metadata tracked; no Spark/Hadoop execution. Glue is different: python-shell jobs run as a subprocess and Spark (glueetl) jobs run in Docker when available.
- ACM — certificates auto-ISSUED; no DNS/HTTP validation occurs.
- Athena without DuckDB — with
ATHENA_ENGINE=mock, results are synthetic (amock_valuerow, or echoed SELECT literals).auto/duckdbgives real SQL on S3 data. - Firehose non-S3 destinations — HTTP, Redshift, OpenSearch, Splunk, Snowflake all stored; no delivery performed. (S3/ExtendedS3 and Iceberg do deliver.)
Impossible locally
These are structural — a single-process emulator cannot simulate them.
- Real VPC networking. Subnets, route tables, and NAT all exist as metadata; packet routing is not simulated.
- Cross-AZ / cross-region replication primitives. DDB global tables and KMS multi-region keys require real regional endpoints. (S3 replication itself delivers as of 1.5.3, with
x-amz-replication-status.) - Real DNS propagation. Route53 changes are visible inside MiniStack only; they don't affect your host's resolver.
- SMTP delivery without a real MTA. Unless
SMTP_HOSTpoints at one (e.g. MailHog), SES emails stay in memory. - Real Kubernetes control plane. EKS runs k3s as a sidecar — powerful, but not byte-identical to EKS.
By-design differences
- No SigV4 signature validation. Any access key/secret works.
- Default account
000000000000(some paths use123456789012interchangeably). - State shared across regions — only for S3 and Aurora DSQL; every other regional service is region-isolated as of 1.5.4 (use unique names for S3/DSQL when exercising two regions). IAM, STS, CloudFront, Route 53, and Organizations are global services in AWS, so account-scoped shared state is correct for them, not a gap.
- Lenient validation. Required fields are checked; optional fields are accepted more permissively than AWS.
- CloudFront response latency — near-zero (no real CDN). Tests that depend on eventual-consistency windows won't see them unless you add a sleep.
Per-service detail: each entry on the Services index page links to a service page with its own "Known limitations" section, calling out the gaps that matter for that specific API surface.