Terraform v1.13.4
+ provider registry.terraform.io/hashicorp/aws ~> 6.31.0 (resolves to >= 6.31.0, < 6.32.0)
Verified the Create function in table_replication.go is identical between v6.31.0 and v6.34.0 (latest release) — the bug is present in all provider versions that include this resource. Upgrading the provider does not fix this.
aws_s3tables_table_replicationaws_s3tables_table_bucket_replication (same pattern, likely same bug)aws_s3tables_table_replication should successfully create a replication configuration for an S3 Tables table.
The resource always fails on creation with BadRequestException: A version token is not specified. This is 100% reproducible across multiple AWS accounts and regions.
Error: creating S3 Tables Table Replication (arn:aws:s3tables:us-east-1:XXXXXXXXXXXX:bucket/my-table-bucket/table/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
with aws_s3tables_table_replication.example["arn:aws:s3tables:us-west-2:YYYYYYYYYYYY:bucket/my-destination-bucket"]
operation error S3Tables: PutTableReplication, https response error StatusCode: 400,
RequestID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
BadRequestException: A version token is not specified.
provider "aws" {
region = "us-east-1"
}
provider "aws" {
alias = "us_west_2"
region = "us-west-2"
}
data "aws_partition" "current" {}
data "aws_service_principal" "current" {
service_name = "s3"
}
resource "aws_iam_role" "replication" {
name = "s3tables-replication-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Principal = {
Service = data.aws_service_principal.current.name
}
Effect = "Allow"
}
]
})
}
resource "aws_s3tables_table_bucket" "source" {
name = "my-source-bucket"
}
resource "aws_s3tables_namespace" "source" {
namespace = "my_namespace"
table_bucket_arn = aws_s3tables_table_bucket.source.arn
}
resource "aws_s3tables_table" "source" {
name = "my_table"
namespace = aws_s3tables_namespace.source.namespace
table_bucket_arn = aws_s3tables_table_bucket.source.arn
format = "ICEBERG"
}
resource "aws_s3tables_table_bucket" "destination" {
provider = aws.us_west_2
name = "my-destination-bucket"
}
# This resource always fails with "A version token is not specified"
resource "aws_s3tables_table_replication" "example" {
table_arn = aws_s3tables_table.source.arn
role = aws_iam_role.replication.arn
rule {
destination {
destination_table_bucket_arn = aws_s3tables_table_bucket.destination.arn
}
}
}
</details>
terraform apply the configuration aboveaws_s3tables_table_replication resource fails with BadRequestException: A version token is not specifiedThis is reproducible on every attempt, across both single-region and cross-region/cross-account setups. Tested in us-east-1 → us-west-2 replication with both same-account and cross-account configurations.
N/A — the error is deterministic and clear from the API response. The issue is in the provider code.
</details>
Claude Code was used to investigate the provider source code and identify the root cause.
Root Cause Analysis:
The Create function in internal/service/s3tables/table_replication.go does not include a VersionToken in the PutTableReplicationInput:
// Current Create function (line ~114)
input := s3tables.PutTableReplicationInput{
Configuration: &configuration,
TableArn: aws.String(tableARN),
// VersionToken is missing
}
The Update function correctly includes the version token (line ~190):
input := s3tables.PutTableReplicationInput{
Configuration: &configuration,
TableArn: aws.String(tableARN),
VersionToken: fwflex.StringFromFramework(ctx, old.VersionToken),
}
The AWS PutTableReplication API requires the VersionToken (obtained from a prior GetTableReplication call) for optimistic concurrency control. The SDK docs describe it as: "A version token from a previous GetTableReplication call. Use this token to ensure you're updating the expected version of the configuration."
Suggested Fix:
The Create function should call GetTableReplication to obtain the current version token before calling PutTableReplication:
// Fetch the current version token
existing, err := conn.GetTableReplication(ctx, &s3tables.GetTableReplicationInput{
TableArn: aws.String(tableARN),
})
if err != nil && !errs.IsA[*awstypes.NotFoundException](err) {
response.Diagnostics.AddError(...)
return
}
input := s3tables.PutTableReplicationInput{
Configuration: &configuration,
TableArn: aws.String(tableARN),
}
if existing != nil && existing.VersionToken != nil {
input.VersionToken = existing.VersionToken
}
The same fix is needed in aws_s3tables_table_bucket_replication (table_bucket_replication.go) which has an identical pattern.
No