Introduction
S3 Cross-Region Replication (CRR) automatically copies objects from a source bucket to a destination bucket in another region. When replication fails, objects uploaded to the source don't appear in the destination, leading to compliance violations, disaster recovery gaps, or data availability issues.
Symptoms
Replication status pending/failed:
```bash $ aws s3api head-object --bucket source-bucket --key my-file.pdf \ --query 'ReplicationStatus'
"PENDING" # Never transitions to COMPLETED # Or: "FAILED" ```
Destination bucket empty:
```bash $ aws s3 ls s3://dest-bucket/
# Empty despite uploads to source $ aws s3 ls s3://source-bucket/ 2024-01-15 10:00:00 my-file.pdf # Exists in source only ```
Replication metrics:
```bash $ aws cloudwatch get-metric-statistics \ --namespace AWS/S3 \ --metric-name ReplicationPendingOperations \ --dimensions Name=BucketName,Value=source-bucket \ --statistics Sum
# High pending count = replication backlog ```
Common Causes
- 1.Versioning disabled - Replication requires versioning on both buckets
- 2.IAM role missing permissions - Role can't read from source or write to destination
- 3.Destination bucket wrong region - Same-region attempted for CRR
- 4.Replication rule not configured - No active replication rule
- 5.Object ownership mismatch - Different AWS accounts require ACL handling
- 6.Encryption mismatch - KMS keys not accessible in destination region
- 7.Filter mismatch - Object doesn't match replication rule filter
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Step 1: Check Versioning on Both Buckets
```bash # Source bucket versioning aws s3api get-bucket-versioning --bucket source-bucket
# Must show: "Status": "Enabled"
# Destination bucket versioning aws s3api get-bucket-versioning --bucket dest-bucket
# Must also be enabled ```
Enable versioning:
```bash aws s3api put-bucket-versioning --bucket source-bucket \ --versioning-configuration Status=Enabled
aws s3api put-bucket-versioning --bucket dest-bucket \ --versioning-configuration Status=Enabled ```
Step 2: Verify Replication Configuration
```bash # Check source bucket replication config aws s3api get-bucket-replication --bucket source-bucket
# Should show rules with destination { "Role": "arn:aws:iam::account:role/replication-role", "Rules": [ { "ID": "rule-1", "Status": "Enabled", "Destination": { "Bucket": "arn:aws:s3:::dest-bucket", "StorageClass": "STANDARD" } } ] } ```
If missing, create replication configuration:
aws s3api put-bucket-replication --bucket source-bucket \
--replication-configuration '{
"Role": "arn:aws:iam::account:role/s3-replication-role",
"Rules": [{
"ID": "replicate-all",
"Status": "Enabled",
"Priority": 1,
"DeleteMarkerReplication": {"Status": "Disabled"},
"Filter": {},
"Destination": {
"Bucket": "arn:aws:s3:::dest-bucket",
"StorageClass": "STANDARD"
}
}]
}'Step 3: Verify IAM Role Permissions
```bash # Get replication role aws iam get-role --role-name s3-replication-role
# Check role permissions aws iam get-role-policy --role-name s3-replication-role --policy-name s3-replication-policy ```
Required permissions for source:
{
"Effect": "Allow",
"Action": [
"s3:GetReplicationConfiguration",
"s3:ListBucket",
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::source-bucket",
"arn:aws:s3:::source-bucket/*"
]
}Required permissions for destination:
{
"Effect": "Allow",
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags",
"s3:ObjectOwnerOverrideToBucketOwner"
],
"Resource": "arn:aws:s3:::dest-bucket/*"
}Create role if missing:
```bash aws iam create-role --role-name s3-replication-role \ --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "s3.amazonaws.com"}, "Action": "sts:AssumeRole" }] }'
aws iam put-role-policy --role-name s3-replication-role \ --policy-name replication-policy \ --policy-document file://replication-policy.json ```
Step 4: Check Destination Bucket Ownership
```bash # For cross-account replication, destination needs owner override aws s3api get-bucket-ownership-controls --bucket dest-bucket
# Should show: "ObjectOwnership": "BucketOwnerPreferred"
# Set if missing aws s3api put-bucket-ownership-controls --bucket dest-bucket \ --ownership-controls '{ "Rules": [{ "ObjectOwnership": "BucketOwnerPreferred" }] }' ```
Step 5: Verify KMS Encryption Configuration
For encrypted objects:
```bash # Check source bucket encryption aws s3api get-bucket-encryption --bucket source-bucket
# For SSE-KMS, destination needs key access # Replication config must specify destination key:
aws s3api put-bucket-replication --bucket source-bucket \ --replication-configuration '{ "Role": "arn:aws:iam::account:role/replication-role", "Rules": [{ "Status": "Enabled", "Destination": { "Bucket": "arn:aws:s3:::dest-bucket", "EncryptionConfiguration": { "ReplicaKmsKeyID": "arn:aws:kms:dest-region:account:key/key-id" } } }] }'
# Role needs KMS permissions: { "Effect": "Allow", "Action": ["kms:Decrypt", "kms:Encrypt"], "Resource": ["arn:aws:kms:source-region:account:key/source-key", "arn:aws:kms:dest-region:account:key/dest-key"] } ```
Step 6: Check Replication Rule Filter
```bash # If rule has filter, object must match aws s3api get-bucket-replication --bucket source-bucket \ --query 'ReplicationConfiguration.Rules[*].Filter'
# Filter examples: # Prefix: "logs/" - Only objects with logs/ prefix replicate # Tags: key=value - Only objects with specific tag replicate
# Upload test object matching filter aws s3 cp test.log s3://source-bucket/logs/test.log # Check replication status aws s3api head-object --bucket source-bucket --key logs/test.log \ --query 'ReplicationStatus' ```
Step 7: Monitor Replication Metrics
```bash # Check pending operations aws cloudwatch get-metric-statistics \ --namespace AWS/S3 \ --metric-name BytesPendingReplication \ --dimensions Name=BucketName,Value=source-bucket \ --statistics Sum \ --period 300
# Check replication latency aws cloudwatch get-metric-statistics \ --namespace AWS/S3 \ --metric-name ReplicationLatency \ --dimensions Name=BucketName,Value=source-bucket \ --statistics Maximum ```
Step 8: Replicate Existing Objects
```bash # Replication only applies to new objects by default # Existing objects don't replicate
# Use S3 Batch Replication for existing objects aws s3 create-job \ --account-id account-id \ --operation '{ "S3BatchReplicationOperation": { "BucketArn": "arn:aws:s3:::source-bucket" } }' \ --manifest '{ "Spec": { "Format": "S3InventoryReport_CSV_2016-11-30", "BucketArn": "arn:aws:s3:::inventory-bucket" } }' \ --report '{ "BucketArn": "arn:aws:s3:::report-bucket", "Format": "Report_CSV_20180220", "Enabled": true }' \ --role-arn arn:aws:iam::account:role/batch-replication-role ```
Step 9: Check for Object Lock Configuration
```bash # Object Lock can affect replication aws s3api get-object-lock-configuration --bucket source-bucket
# If Object Lock enabled, destination must also have it aws s3api put-object-lock-configuration --bucket dest-bucket \ --object-lock-configuration '{ "ObjectLockEnabled": "Enabled", "Rule": { "DefaultRetention": { "Mode": "GOVERNANCE", "Days": 30 } } }' ```
Step 10: Troubleshoot Specific Objects
```bash # Check object replication status aws s3api head-object --bucket source-bucket --key specific-object \ --query '{Status:ReplicationStatus,Version:VersionId}'
# FAILED status indicates: # - Encryption key issue # - Permission denied # - Destination bucket problem
# Check replication time control metrics (if enabled) aws s3api get-bucket-replication --bucket source-bucket \ --query 'ReplicationConfiguration.Rules[*].Metrics' ```
Verification
```bash # Upload new object aws s3 cp test-file.txt s3://source-bucket/test-file.txt
# Wait 1-2 minutes # Check replication status aws s3api head-object --bucket source-bucket --key test-file.txt \ --query 'ReplicationStatus'
# Should show: COMPLETED
# Verify in destination aws s3 ls s3://dest-bucket/test-file.txt
# Should exist ```
Replication Status Values
| Status | Meaning |
|---|---|
| PENDING | Queued for replication |
| COMPLETED | Successfully replicated |
| FAILED | Replication error |
| REPLICA | This is a replica object |
Related Issues
- [Fix AWS S3 Bucket Policy Denied](/articles/fix-aws-s3-bucket-policy-denied)
- [Fix AWS S3 Lifecycle Rule Not Expiring](/articles/fix-aws-s3-lifecycle-rule-not-expiring)
- [Fix AWS S3 CORS Config Missing](/articles/fix-aws-s3-cors-config-missing)
Related Articles
- [AWS troubleshooting: Fix IAM Permission Denied - Complete Tro](fix-iam-permission-denied)
- [AWS cloud troubleshooting: AWS ACM Certificate Pending Validation Because the](aws-acm-certificate-pending-validation-wrong-route53-zone)
- [AWS cloud troubleshooting: AWS ALB Returns 502 Because the Target Closed the ](aws-alb-502-target-closed-connection-keepalive-timeout-mismatch)
- [AWS cloud troubleshooting: Fix AWS ALB CreateListener TargetGroupNotFound Err](aws-alb-createlistener-targetgroupnotfound)
- [AWS cloud troubleshooting: Fix Aws Alb Lambda 502 Bad Gateway Issue in AWS](aws-alb-lambda-502-bad-gateway)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix AWS S3 Cross-Region Replication Not Working", "description": "Troubleshoot S3 replication failures. Fix IAM roles, bucket versioning, replication rules, and CRR configuration issues.", "url": "https://www.fixwikihub.com/fix-aws-s3-replication-not-working", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-01T21:25:07.915Z", "dateModified": "2026-04-01T21:25:07.915Z" } </script>