This error occurs when attempting a point-in-time restore in DynamoDB with a restore timestamp that falls outside the valid recovery window. The specified restore time must be between EarliestRestorableDateTime and LatestRestorableDateTime, which is typically the last 35 days but always excludes the last 5 minutes.
The InvalidRestoreTimeException error in DynamoDB indicates that you're attempting to restore a table to a point in time that is not available or valid for restoration. DynamoDB maintains point-in-time recovery backups within specific time boundaries, and attempting to restore outside these boundaries will trigger this error. This happens because: 1. **LatestRestorableDateTime is 5 minutes in the past** - You cannot restore to the current moment due to replication lag 2. **EarliestRestorableDateTime is 35 days ago by default** - You cannot restore beyond your retention window 3. **PITR was recently enabled** - If PITR was just enabled, you can only restore to times after it was enabled 4. **Restore time must be exact** - The timestamp must fall within the valid boundary window This is a client-side validation error (HTTP 400) that prevents invalid restore operations.
First, verify the valid restore time boundaries for your table:
# Using AWS CLI
aws dynamodb describe-continuous-backups --table-name YourTableName --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription'
# Output example:
# {
# "PointInTimeRecoveryStatus": "ENABLED",
# "EarliestRestorableDateTime": "2025-11-14T10:30:00.000Z",
# "LatestRestorableDateTime": "2025-12-29T09:25:00.000Z"
# }Key fields to note:
- PointInTimeRecoveryStatus must be "ENABLED"
- EarliestRestorableDateTime is the oldest restore point (usually 35 days ago)
- LatestRestorableDateTime is the newest restore point (usually 5 minutes ago)
- Your restore time MUST fall between these two times
Calculate a valid restore time that falls within the recovery window:
# Using Python to calculate a valid restore time
python3 << 'EOF'
from datetime import datetime, timedelta
# Get current time and subtract 5 minutes for LatestRestorableDateTime
now = datetime.utcnow()
latest_restorable = now - timedelta(minutes=5)
earliest_restorable = now - timedelta(days=35)
print(f"Current time: {now.isoformat()}Z")
print(f"Latest restorable (now - 5 min): {latest_restorable.isoformat()}Z")
print(f"Earliest restorable (now - 35 days): {earliest_restorable.isoformat()}Z")
print()
print("Valid restore times must be between:")
print(f" {earliest_restorable.isoformat()}Z")
print(f" and")
print(f" {latest_restorable.isoformat()}Z")
# Example: restore to 1 hour ago (safe choice)
one_hour_ago = now - timedelta(hours=1)
print(f"
Safe choice - restore to 1 hour ago: {one_hour_ago.isoformat()}Z")
EOFImportant timing rules:
- Never try to restore to "now" - always subtract at least 5 minutes
- Always include milliseconds (.000Z format) in timestamps
- Use UTC timestamps (Z suffix)
- Consider restoring to a time when you know a problem occurred
Ensure Point-in-Time Recovery has been enabled long enough to cover your restore time:
# Check when PITR was enabled
aws dynamodb describe-continuous-backups --table-name YourTableName --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription.PointInTimeRecoveryStatus'
# If just enabled, wait a few minutes before attempting restore
# PITR must be active for at least a few minutes before restore points exist
# If PITR is disabled, enable it first
aws dynamodb update-continuous-backups --table-name YourTableName --point-in-time-recovery-specification 'PointInTimeRecoveryEnabled=true'
# Wait for PITR activation (typically 1-2 minutes)
sleep 120
# Verify restore points are available
aws dynamodb describe-continuous-backups --table-name YourTableName --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription.EarliestRestorableDateTime'PITR activation considerations:
- Takes 1-2 minutes to become active after enabling
- First restore point must be created (wait a few minutes)
- If just enabled, only restore to times after activation
Execute the restore operation with a valid timestamp:
# Method 1: Restore to specific point in time (at least 5 minutes ago)
RESTORE_TIME="2025-12-29T08:00:00.000Z"
aws dynamodb restore-table-to-point-in-time --source-table-name YourTableName --target-table-name YourTableName-restored --restore-date-time "$RESTORE_TIME"
# Method 2: Restore to latest available time (safest option)
aws dynamodb restore-table-to-point-in-time --source-table-name YourTableName --target-table-name YourTableName-restored --use-latest-restorable-time
# Monitor restore progress
aws dynamodb describe-table --table-name YourTableName-restored --query 'Table.TableStatus'Restore options:
- Use --use-latest-restorable-time for the safest approach (no manual time calculation)
- If specifying time manually, use ISO 8601 format with milliseconds: YYYY-MM-DDTHH:MM:SS.000Z
- Always ensure restore time is at least 5 minutes in the past
- Target table must have a unique name (cannot overwrite source)
Add time validation before attempting restore operations:
// AWS SDK v3 for JavaScript
import { DynamoDBClient, RestoreTableToPointInTimeCommand, DescribeContinuousBackupsCommand } from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({ region: 'us-east-1' });
async function restoreTableWithValidation(sourceTable, targetTable, desiredRestoreTime) {
try {
// Get current restore window
const backupsCmd = new DescribeContinuousBackupsCommand({
TableName: sourceTable
});
const backups = await client.send(backupsCmd);
const { PointInTimeRecoveryDescription } = backups.ContinuousBackupsDescription;
if (PointInTimeRecoveryDescription.PointInTimeRecoveryStatus !== 'ENABLED') {
throw new Error('PITR is not enabled on ' + sourceTable);
}
const earliest = new Date(PointInTimeRecoveryDescription.EarliestRestorableDateTime);
const latest = new Date(PointInTimeRecoveryDescription.LatestRestorableDateTime);
const restoreTime = new Date(desiredRestoreTime);
// Validate restore time is within bounds
if (restoreTime < earliest) {
throw new Error(
'Restore time is before EarliestRestorableDateTime (' +
earliest.toISOString() + ')'
);
}
if (restoreTime > latest) {
throw new Error(
'Restore time is after LatestRestorableDateTime (' +
latest.toISOString() + '). Try a time at least 5 minutes ago.'
);
}
// Perform the restore
const restoreCmd = new RestoreTableToPointInTimeCommand({
SourceTableName: sourceTable,
TargetTableName: targetTable,
RestoreDateTime: restoreTime
});
console.log('Restoring ' + sourceTable + ' to ' + restoreTime.toISOString());
return await client.send(restoreCmd);
} catch (error) {
if (error.name === 'InvalidRestoreTimeException') {
console.error('Invalid restore time:', error.message);
console.error('Try using --use-latest-restorable-time instead');
}
throw error;
}
}Validation checklist:
- Always check PITR status before attempting restore
- Validate restore time against EarliestRestorableDateTime and LatestRestorableDateTime
- Catch InvalidRestoreTimeException and provide helpful error messages
- Consider using --use-latest-restorable-time to eliminate time calculations
If running in a distributed environment, ensure proper time synchronization:
# For EC2 instances or servers, ensure NTP is running
sudo systemctl status ntp # or chronyd for newer systems
# Check system clock against AWS time
ntpdate -q time.nist.gov
# On AWS Lambda or managed services, time is typically synchronized automatically
# For Docker containers, ensure --cap-add=SYS_TIME if adjusting time
docker run --cap-add=SYS_TIME myimageTime synchronization best practices:
- Ensure systems running restore operations have synchronized clocks
- Use NTP or chrony for Linux systems
- AWS managed services (Lambda, ECS) handle time sync automatically
- Time zone issues: Always use UTC timestamps
- Consider using server time from AWS API responses to avoid local clock skew
Implement monitoring and alerting for restore operations:
# Using CloudWatch metrics for monitoring
aws cloudwatch put-metric-alarm --alarm-name DynamoDB-RestoreOperationFailures --alarm-description "Alert on failed DynamoDB restore attempts" --metric-name UserErrors --namespace AWS/DynamoDB --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --dimensions Name=TableName,Value=YourTableName
# Log restore operations with timestamps
aws dynamodb restore-table-to-point-in-time --source-table-name YourTableName --target-table-name YourTableName-restored --use-latest-restorable-time 2>&1 | tee -a restore-operations.logMonitoring recommendations:
- Log all restore attempts with requested and actual restore times
- Set up alerts for InvalidRestoreTimeException errors
- Monitor PITR status regularly
- Test restore procedures monthly in non-production
- Document baseline restore times for your tables
## Point-in-Time Recovery Timing Deep Dive
### The 5-Minute Buffer Window
DynamoDB maintains a 5-minute buffer between the current time and the latest restorable datetime. This buffer exists because:
- Backups require time to replicate across availability zones
- Ensures data consistency across regions for global tables
- Prevents restoring to a state before recent writes have fully propagated
- Provides a safety margin against clock skew in distributed systems
### Time Precision and Milliseconds
All DynamoDB timestamps require millisecond precision (.000Z format). Using timestamp formats without milliseconds will fail validation. Accepted format: YYYY-MM-DDTHH:MM:SS.000Z (UTC only).
### Recovery Period Configuration
While the default retention period is 35 days, you can configure this:
# View current recovery period
aws dynamodb describe-continuous-backups --table-name YourTableName --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription'
# To extend retention, use AWS Backup (up to 35 years)
aws backup create-backup-plan --backup-plan file://backup-plan.jsonIf you decrease the recovery period, your EarliestRestorableDateTime immediately moves forward, removing access to older backups.
### Clock Skew Implications
Distributed systems can experience clock skew (different servers having different times). The 5-minute buffer helps mitigate issues where:
- Client clock is slightly ahead of AWS systems
- Multiple regions have slight time differences
- Automated systems attempt to restore immediately after an event
### Cascading Restore Effects
- First restore creates a new table (snapshot)
- Second restore can use the first restored table as source (requires separate PITR enable)
- Restore operations are atomic - either fully succeeds or fully fails
- Failed restores don't create partial tables
### Cross-Region Restore Timing
When restoring across regions:
- Each region maintains its own PITR recovery window
- Restore times must be valid in the SOURCE region
- Replicated tables in Global Tables have independent recovery windows
- Time zone handling is critical for manual timestamps
### Operational Considerations
1. Scheduled Restores: Schedule restore operations for at least 10 minutes in the past to provide safety margin
2. Disaster Recovery Automation: Always use --use-latest-restorable-time in automated scripts
3. Manual Testing: When manually testing restores, use times 30+ minutes in the past
4. Time Zone Conversion: If specifying times manually, always convert to UTC first
5. CI/CD Pipelines: Build restore validation into deployment pipelines
### Cost Implications
Restore operations themselves have no additional charge, but:
- Restored table consumes write capacity while populating
- Additional backup storage costs if keeping both original and restored tables
- Cross-region restores have data transfer costs
### Troubleshooting Timeline Issues
If you encounter InvalidRestoreTimeException errors:
1. First, check the restore window - Get actual EarliestRestorableDateTime and LatestRestorableDateTime
2. Subtract extra buffer - If near the window boundaries, try 30 minutes in the past instead
3. Verify PITR activation - If recently enabled, wait 5+ minutes before attempting restore
4. Check server clocks - Especially important for on-premises servers or EC2 instances
5. Use AWS timestamps - Let AWS calculate times rather than manual timestamps
### Best Practices Summary
1. Always use --use-latest-restorable-time unless you have a specific recovery point
2. Implement client-side validation of restore times before attempting operations
3. Add 5+ minute buffer to any automatically calculated restore times
4. Monitor PITR status with CloudWatch alarms
5. Test restore procedures regularly (but use --use-latest-restorable-time for safety)
6. Document your recovery time objective (RTO) and recovery point objective (RPO) requirements
7. For critical tables, consider AWS Backup for longer retention periods
ValidationException: The provided key element does not match the schema
How to fix "ValidationException: The provided key element does not match the schema" in DynamoDB
UnrecognizedClientException: The security token included in the request is invalid
How to fix "UnrecognizedClientException: The security token included in the request is invalid" in DynamoDB
TransactionCanceledException: Transaction cancelled
How to fix "TransactionCanceledException: Transaction cancelled" in DynamoDB
RequestLimitExceeded: Throughput exceeds the current throughput limit for your account
How to fix "RequestLimitExceeded: Throughput exceeds the current throughput limit for your account" in DynamoDB
InternalServerError: Internal Server Error
How to fix "InternalServerError" in DynamoDB