What's Changed
New Contributors
- @ryuzo-hayashi made their first contribution in #2509
- @zalefin made their first contribution in #2511
- @chris-plucker made their first contribution in #2515
- @chandra-purbia made their first contribution in #2513
[1.5.36] — 2026-11-02
Added
- CloudFormation —
AWS::Events::Archive— a template with an EventBridge archive was refused as an unrecognized resource type, though the archive API itself was supported. It now creates the archive:Refis the archive name, a generated one is the logical id cut to 35 characters,-and 12 letters and digits, andFn::GetAtt Arnis its ARN;Fn::GetAtton any other property rolls the stack back with AWS's "must be a readonly property in schema". The event pattern is stored compact, with non-ASCII characters as written and each object's keys in the order AWS stores them. A changedDescription,RetentionDays,EventPatternorKmsKeyIdentifierupdates the archive in place, and one left out of the template keeps its value (an emptyKmsKeyIdentifierclears the key); an update that leaves none of the first three fails with the handler's message, so rolling an update back to such a template endsUPDATE_ROLLBACK_FAILED, as on AWS. A newArchiveNamereplaces the archive, a newSourceArnreplaces a generated one and is refused for a custom name, and a stack delete removes it. Early Validation refuses a template that breaks the resource schema (a missingSourceArn, anArchiveNametoo long, too short or outside its pattern, a value of the wrong type, an unsupported property, aKmsKeyIdentifierover 2048 characters) and a new archive whose name is taken, with AWS's messages and in AWS's order. The handler refuses what the schema lets through, as on AWS: a name orSourceArnoutside the API's pattern, a negativeRetentionDays, a KMS key that does not exist, and relays EventBridge's own refusals (a taken name, a bus that does not exist, an invalid pattern) in itsResource handler returned messageform with the SDK's suffix. Measured against a real account in eu-west-1. Contributed by @toby6578. - CloudFormation —
AWS::CloudFormation::StackSetwith one stack instance in its own account and Region — a template with a StackSet was refused as an unrecognized resource type. ASELF_MANAGEDStackSet whose oneStackInstancesGrouptargets the stack's own account and Region now deploys its inlineTemplateBodyas a stack instance through the nested-stack engine, which updates it, rolls a failed update back with the stack and deletes it.Refreturns theStackSetId;DescribeStackSet(by name, or byStackSetIdalso once deleted) andListStackInstancesanswer with the shapes of a real-AWS capture. Any other StackSet fails the resource with an error naming what is deployed. Contributed by @chris-plucker. - S3 Control — account-level public access block —
PutPublicAccessBlock,GetPublicAccessBlockandDeletePublicAccessBlockon/v20180820/configuration/publicAccessBlock, which answeredInvalidURI. The configuration is held per account and applies in every region, and its settings apply to the account's buckets with their own (BlockPublicPolicyrefuses a public bucket policy);DeletePublicAccessBlockis authorized ass3:PutAccountPublicAccessBlock. An unsetGetPublicAccessBlockanswers 404NoSuchPublicAccessBlockConfigurationcarrying<AccountId>inside<Error>, and an unsupported method 405MethodNotAllowedwithResourceTypeACCOUNT_PUBLIC_ACCESS_BLOCK. Responses and errors verified against a real AWS account. Contributed by @pingedbrain. - SSM — documents and automation executions —
CreateDocument,DescribeDocument,GetDocument,ListDocuments,DeleteDocument, andStartAutomationExecution,GetAutomationExecution,DescribeAutomationExecutions,StopAutomationExecution, which answeredInvalidAction. Documents are stored per account and region with AWS's real shapes:Hashis the SHA-256 of the verbatim content,StatusgoesCreating→Active,PlatformTypesdefaults to all three platforms,CreatedDateis sent as epoch seconds,GetDocumentreturnsDocumentFormatJSONby default with the content re-serialized in AWS's canonical JSON layout, and a document's declaredparametersappear in the description. Content is validated on create: unparsable JSON/YAML answersInvalidDocumentContentwith AWS's "not well-formed" messages, an Automation document withoutmainStepsMissing steps in "mainSteps"., an unknown step actionUnknown action: <action>, a badDocumentTypeAWS'sValidationException, a duplicate nameDocumentAlreadyExists, and a name with a prefix AWS reserves (aws,amazon,amzn,AWSEC2,AWSConfigRemediation,AWSSupport) is refused. Executions build realStepExecutionsfrom the document'smainSteps(oneStepExecutionIdeach, inputs JSON-stringified with{{ param }}references resolved from declared defaults and passedParameters), exposeCurrentStepName/CurrentActionwhile running, and run the steps they can:aws:sleepwaits its ISO-8601 duration,aws:executeAwsApidispatches into the emulatedssmAPI,aws:runCommanddispatchesSendCommand; a step MiniStack cannot execute fails the execution with AWS'sFailureMessage/FailureDetailsshape instead of reporting a fabricated success, andStopAutomationExecutionlandsCancelled; underAUTH=truea step calls the API with the permissions of the document'sassumeRole, or of the caller, so a step the caller may not run fails withAccessDeniedException.StartAutomationExecutionanswersAutomationDefinitionNotFoundExceptionfor a document the account doesn't hold andInvalidAutomationExecutionParametersExceptionfor undeclared parameters. Responses and errors verified against a real AWS account. Contributed by @pingedbrain.
Fixed
- API Gateway — REST, HTTP and WebSocket APIs answer callers from any account — an execute-api call reached an API only in the account its access key selected, so an unsigned call, which MiniStack serves as the default account, or a call signed by another account answered 404
{"message": "Not Found"}for an API another account owns. On AWS an execute-api URL reaches its API whatever the caller (captured on AWS): a method without authorization answered 200 unsigned, with another account'sAuthorizationheader and when signed by another account. The call now runs as the API's owner account, and the caller is authenticated in its own account. UnderAUTH=trueanAWS_IAMmethod answers a caller from another account that no REST API policy grants with 403AccessDeniedException{"Message": "User: <caller> is not authorized to access this resource"}, as AWS does, and a policy allowing that account lets it in. An HTTP or WebSocket API is served as its owner the same way. Contributed by @chandra-purbia. - CloudFormation — validation and provisioning errors carry no
OperationStatus—DescribeEventsgave a create or update'sVALIDATION_ERRORandPROVISIONING_ERROReventsOperationStatusFAILED, which AWS's don't have. Measured against a real account in eu-west-1. Contributed by @toby6578. - CloudFormation — change sets run Early Validation — a change set whose template fails pre-deployment validation was created and failed only on execution;
CreateChangeSetnow checks the resources it adds or modifies and fails it as AWS does:FAILEDwith "The following hook(s)/validation failed: [AWS::EarlyValidation::...]", naming theResourceExistenceCheckandPropertyValidationhooks in the order of their first errors, keeping its changes.DescribeEventsfor the change set (OperationTypeCREATE_CHANGESET) lists, newest first, its outcome, its validation errors by logical id and its start, and the stack's own events don't include them; aCREATEorUPDATEchange set that succeeds has its start andSUCCEEDED, and one with no changes has none.DisableValidationskips it.ExecuteChangeSeton a failed change set answers AWS's "cannot be executed in its current status of [FAILED]". AWS let some invalid in-place changes through to fail at execution, from a change set orUpdateStack, and refused others at validation; MiniStack refuses them all at validation. Measured against a real account in eu-west-1. Contributed by @toby6578. - CloudWatch Logs — every stored event has an
eventId— events written by a Lambda, a CodeBuild build or a DynamoDB import came back fromFilterLogEventswithout theeventIdAWS always returns, soaws logs tail --followstopped withKeyError: 'eventId'on a Lambda's log group. Contributed by @chandra-purbia. - Cognito — a failing PreTokenGeneration Lambda fails the request — a trigger that returned an error, including running past its own timeout, was logged and the token issued without its claims, and one that could not be invoked did the same unless
MINISTACK_COGNITO_PRETOKEN_STRICT=1turned either into a 500. As on AWS,InitiateAuth,RespondToAuthChallenge, the refresh flows and/oauth2/tokennow answer 400UserLambdaValidationException<trigger> failed with error <errorMessage>.for the first andUnexpectedLambdaExceptionfor the second;/oauth2/tokencarries the text and code inerror.MINISTACK_COGNITO_PRETOKEN_STRICTis removed. Contributed by @ryuzo-hayashi. - Cognito — PreSignUp and CustomMessage Lambda errors — a Lambda that returned an error failed the request with its raw error body as the message; it is now AWS's
UserLambdaValidationExceptiontext,PreSignUp failed with error <errorMessage>.andCustomMessage failed with error <errorMessage>. - ElastiCache — replication group endpoints after a restart — with persisted state, a replication group's containers were respawned on restart but its
PrimaryEndpoint,ReaderEndpoint, members'ReadEndpointandConfigurationEndpointkept the old container's address; they now report the new one, as cache clusters already did. Reported by @chris-plucker. - EventBridge — an archive created without a description or a pattern has neither —
DescribeArchivereturned"Description": ""and"EventPattern": ""; it now leaves both keys out, as AWS does. Contributed by @toby6578. - EventBridge —
CreateArchiverefusals — an archive on an event bus that does not exist was created; it now answersResourceNotFoundException"Event bus does not exist.", and a taken name'sResourceAlreadyExistsExceptionends with a period, as AWS's does. Contributed by @toby6578. - EventBridge —
PutEventsto a bus ARN in another region — an entry naming an event bus ARN in a region other than the request's failed on its own withResourceNotFoundException. AWS refuses the whole request instead: it answered 400ValidationException"Cross-region api call is not allowed." for a bus in the caller's own account (captured on AWS).PutEventsnow answers the same, before any entry is delivered. Contributed by @chandra-purbia. - EventBridge — rule targets in another account —
PutTargetsaccepted an SQS (or other) target in another account without aRoleArn, and the events were then silently dropped. As on AWS, it now answersValidationException"RoleArn is required for target ." for such a target in any region, and with an execution role an SQS target in another account of the same region receives the events, as AWS's cross-account targets do, and underAUTH=trueonly when the queue's policy allows that role. A target in another region is still accepted and not reached. Contributed by @chandra-purbia. - EventBridge — rule targets that are event buses in another account or region —
PutTargetsaccepted such a target and every event was then dropped ("event bus … not found"). An event now reaches the target bus's rules in its owner's account and region, keeping itsaccountandregion; crossing into another region gives it a new id and time. As on AWS, a forwarded event reaches another bus in the same region only once and crosses regions only once (after which it may make one more same-region hop), which also stops a chain of rules from looping, so the per-rule recursion guard is gone.PutTargetsanswers AWS's errors for event bus targets: after its existing ARN checks, 400AccessDeniedExceptionAccess to the resource <role> is denied. Reason: Cross-account pass role is not allowed.for another account's role; then, target by target,Source EventBus and Target EventBus must not be the same.for the rule's own bus andRetry policy is not supported for Event bus targets.for anyRetryPolicy; thenRoleArn is required for target <arn>.for any bus target without a role, the rule's own account and region included (it wasRoleArn is required, and only for another account or region). CloudFormation'sAWS::Events::Rulenow runsPutTargets' checks on create, as it did on update, so a target that is not a well-formed ARN of a supported service now fails the create too. WithAUTH=truetheRoleArnmust name the rule account's role exactly, its trust policy must let EventBridge assume it for the rule (conditions see the rule's account asaws:SourceAccountand its ARN asaws:SourceArn), and it must be allowedevents:PutEventson the bus, withaws:RequestedRegionthe bus's region; a Deny in the bus's policy refuses it, and a bus in another account must also allow it, withevents:eventBusInvocationtruefor its conditions. MiniStack does not model target dead-letter queues, so a refused event is dropped and logged with theERROR_CODEAWS records (NO_PERMISSIONS,THIRD_ACCOUNT_HOP_DETECTEDorTHIRD_REGION_HOP_DETECTED). A schedule whose target is an event bus still publishes to it as before. Recorded with three accounts in eu-west-2, us-east-1 and us-west-2. Contributed by @toby6578. Reported by @lucasmfraser. - KMS — keys in other accounts, missing keys and denials answer as AWS does — another account's key named by key ARN or alias ARN, or by the ciphertext
Decryptis given, is now governed by its key policy in both auth modes. A refusal names the key when it exists and not when it does not; operations AWS does not serve across accounts answerThis operation cannot be called cross account; another Region's ARN answersInvalid arn <region>. A key or alias that does not exist answersNotFoundExceptionbefore any permission check, worded as AWS words it, and a denial no policy allows is HTTP 400 naming the key.DescribeKeycarriesAWSAccountId,GetKeyRotationStatuscarriesKeyId(and no period while rotation is off), and the default key policy has AWS's layout. Recorded with two accounts in us-east-1. Contributed by @Jolley71717. Reported by @kharabasz. - Lambda —
nodejs24.xrefuses callback-based handlers — a handler taking a callback ran onnodejs24.x; as AWS's Node.js 24 runtime does, a handler with three or more parameters that is not a response-streaming handler now fails withRuntime.CallbackHandlerDeprecated"ERROR: AWS Lambda has removed support for callback-based function handlers starting with Node.js 24. …", with the local executor and withLAMBDA_EXECUTOR=docker, and local workers carryAWS_EXECUTION_ENV(AWS_Lambda_<runtime>) as AWS's runtimes do. - Lambda — Node.js functions in a
"type": "module"package underLAMBDA_EXECUTOR=docker— the context shim MiniStack adds to a Node function was written as_msctx_shim.js, which Node loads as an ES module when the package'spackage.jsonsays"type": "module", so every invoke failed withReferenceError: require is not defined in ES module scope. It is now_msctx_shim.cjs, which Node always loads as CommonJS, and the function runs as it does on AWS. Contributed by @Jolley71717. Reported by @evan-burrell. - Lambda — a function with no declared architecture after an arm64 one — with
LAMBDA_EXECUTOR=docker, invoking anarm64function pulled the arm64 image under the shared runtime tag, and a function that declared no architecture then ran that image on an x86 host and failed withexec format error; the host's image is now pulled back and run. - RDS — a cluster master password change is visible before it settles —
ModifyDBClusterwithMasterUserPasswordchanged the password at once and everyDescribeDBClustersreportedavailable, so a client waiting to observe the reset never saw it. As captured from real AWS, theModifyDBClusterresponse and the firstDescribeDBClustersshow the clusteravailablewithPendingModifiedValues.MasterUserPassword****, the next reportsresetting-master-credentials(still pending), and later onesavailablewith nothing pending. A password change on a stopped cluster now fails withInvalidDBClusterStateFault("Db cluster cannot be in the stopped state."), as AWS does. Contributed by @chris-plucker. - RDS — default Aurora cluster parameter groups —
DescribeDBClusterParameterGroupsandDescribeDBClusterParametersansweredDBParameterGroupNotFoundfor a default group such asdefault.aurora-postgresql16, and a new cluster reporteddefault.aurora-postgresqlwith no version; each Aurora family in the engine-version catalog now has itsdefault.<family>group, and a cluster created without a parameter group reports its engine version's default, as AWS names it; an unfilteredDescribeDBClusterParameterGroupslists a default group only once it exists in the account (described by name or used by a cluster), as AWS does, and a major engine upgrade moves a cluster on the default group to the target version's default while keeping a custom group (the upgrade is reported as pending, thenupgrading, then done, and member instances on the old default group follow), and a default group cannot be modified (InvalidParameterValue"Cannot modify a default parameter group.") or deleted (InvalidDBParameterGroupState"Default DBClusterParameterGroup cannot be deleted: "), while a reset succeeds; deleting a cluster parameter group that does not exist answers "DBClusterParameterGroup not found: ". Contributed by @chris-plucker. - RDS —
ModifyDBClustermajor upgrades needAllowMajorVersionUpgrade— a change to another major version went through without it; it now answers 400InvalidParameterCombination"The AllowMajorVersionUpgrade flag must be present when upgrading to a new major version.", as AWS's Aurora upgrade guide shows. - S3 —
TaggingonCreateMultipartUpload— thex-amz-taggingheader was ignored, so an object uploaded in parts had no tags, including S3-to-S3 copies byaws s3 cpof objects large enough to copy in parts. The tags now land on the completed object's version, decide tag-filtered replication rules and carry to the replica, as with PutObject; more than 10 answer 400BadRequest"Object tags cannot be greater than 10" at create time, and an untagged multipart upload that overwrites a tagged object leaves it without tags, as on AWS. Contributed by @zalefin. - S3 — an overwritten object's tags and ACL —
PutObjectand a POST upload without tags or an ACL kept the overwritten object's, soGetObjectTaggingandGetObjectAclreported them on the new object; as on AWS, the new object starts with no tags and the default ACL. - S3 Tables — Iceberg
last-column-idcounts nested fields — a table created through the Iceberg REST catalog reported the number of top-level fields as itslast-column-id, andadd-schemaadvanced it to the highest top-level id, so with a list, map or struct column a client's next column reused a nested field's id and Trino'sADD COLUMNfailed withMultiple entries with same key. It is now the highest field id anywhere in the schema, a list'selement-idand a map'skey-idandvalue-idincluded, as on AWS. Contributed by @Jolley71717. Reported by @Wazabit. - S3 Tables — Iceberg REST
dropTableanddropNamespace—DELETE …/namespaces/{ns}/tables/{table}andDELETE …/namespaces/{ns}answeredUnknown Iceberg REST path, so Trino'sDROP TABLEfailed. A table is now dropped, with its metadata files, when the call setspurgeRequested=true, so a table created again under the same name starts empty; without the flag the answer is AWS'spurge_enablederror. A namespace that still holds tables answersnamespace_not_empty.HEADon a namespace is served, andHEADon a table or namespace answers 204 as AWS does. Contributed by @Jolley71717. Reported by @Wazabit. - S3 Tables — Iceberg REST
createTablelocation andstage-create— a"location": null, which Trino sends for a table without a location, was stored as the table's location, so Trino failed withCannot parse to a string value: location: null. As on AWS, the location is now always the one S3 Tables assigns, whatever the client sends, and a create withoutstage-create, or with a null one, answers 400required_field_is_null"stage-create is a required field and cannot be null". Reported by @Wazabit. - S3 Tables — Iceberg REST
createTablerenumbers field ids — the client's field ids were kept; as on AWS they are now renumbered from 1, each struct's fields before their nested types, withlast-column-id, the partition spec's and the sort order'ssource-ids following the new ids, and awrite-orderbecomes the table's sort order. - Secrets Manager — a replicated secret reports its own
PrimaryRegion—DescribeSecretandListSecretsreturnedPrimaryRegiononly for a replica, so a client reading the Region of a secret it replicated got nothing; the primary of a replicated secret now reports its own Region, as AWS does, a replica still reports its source Region, and a secret that is not replicated still has none. Contributed by @chris-plucker. - Step Functions —
ecs:runTask.syncfails with the task — the state waited for the task to stop and then always succeeded, with the whole DescribeTasks response as its result. As on AWS, a task whose essential container exits non-zero, or that never starts, now fails the state withStates.TaskFailed, the stopped task as JSON in PascalCase (epoch-millisecond timestamps) as the cause, soRetryandCatchapply; otherwise the state's result is that task document. Reported by @lucasmfraser.