DynamoDB returns InvalidExportTimeException when you try to export a table using an ExportTime that falls outside the point-in-time recovery (PITR) retention window. This error occurs with ExportTableToPointInTime API when the specified timestamp is either too old (beyond PITR retention) or in the future.
Fixes InvalidExportTimeException: The specified ExportTime is outside of the point in time recovery window
# Check PITR status for a table
aws dynamodb describe-continuous-backups --table-name "MyTable"
# Get current time in UTC for reference
date -u +"%Y-%m-%dT%H:%M:%SZ"
# Calculate valid time range
aws dynamodb describe-continuous-backups --table-name "MyTable" --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription.[EarliestRestorableDateTime, LatestRestorableDateTime]'# Check PITR status for a tableaws dynamodb describe-continuous-backups --table-name "MyTable"# Get current time in UTC for referencedate -u +"%Y-%m-%dT%H:%M:%SZ"# Calculate valid time rangeaws dynamodb describe-continuous-backups --table-name "MyTable" --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription.[EarliestRestorableDateTime, LatestRestorableDateTime]'InvalidExportTimeException: The specified ExportTime is outside of the point in time recovery window
The InvalidExportTimeException error in DynamoDB indicates that the timestamp you specified for a point-in-time export is not within the valid time range supported by DynamoDB's point-in-time recovery (PITR) feature. This error typically occurs in several scenarios: 1. **ExportTime too old**: The timestamp is older than the PITR retention period (default 35 days, configurable up to 35 days) 2. **ExportTime in the future**: The timestamp is ahead of the current time 3. **ExportTime before table creation**: The timestamp predates when the table was created 4. **ExportTime during PITR disabled period**: The timestamp falls within a time when PITR was disabled for the table 5. **Clock skew issues**: System clock differences between your application and AWS services DynamoDB's point-in-time recovery allows you to restore a table to any second within the retention period. When exporting data, you must specify an ExportTime that falls within this window. The export creates a snapshot of the table as it existed at that exact moment.
First, check if point-in-time recovery is enabled and determine the valid time range:
# Check PITR status for a table
aws dynamodb describe-continuous-backups --table-name "MyTable"
# Get current time in UTC for reference
date -u +"%Y-%m-%dT%H:%M:%SZ"
# Calculate valid time range
aws dynamodb describe-continuous-backups --table-name "MyTable" --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription.[EarliestRestorableDateTime, LatestRestorableDateTime]'Key checks:
- Verify PITR status is "ENABLED"
- Ensure ExportTime falls between EarliestRestorableDateTime and LatestRestorableDateTime
- Confirm ExportTime is not in the future
Determine the exact time window available for exports:
// Calculate valid export time range
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB({ region: 'us-east-1' });
async function getValidExportTimeRange(tableName) {
const response = await dynamodb.describeContinuousBackups({
TableName: tableName
}).promise();
const pitr = response.ContinuousBackupsDescription.PointInTimeRecoveryDescription;
const earliest = new Date(pitr.EarliestRestorableDateTime);
const latest = new Date(pitr.LatestRestorableDateTime);
const now = new Date();
return {
earliest,
latest: latest < now ? latest : now,
isValidTime: (timestamp) => {
const time = new Date(timestamp);
return time >= earliest && time <= latest;
}
};
}Time validation rules:
- ExportTime must be ≥ EarliestRestorableDateTime
- ExportTime must be ≤ LatestRestorableDateTime (or current time if earlier)
- ExportTime must use ISO 8601 format with timezone (preferably UTC)
Adjust your ExportTime to fall within the valid range:
// Adjust export time to valid range
async function getValidExportTime(tableName, desiredTime) {
const range = await getValidExportTimeRange(tableName);
const desired = new Date(desiredTime);
if (range.isValidTime(desired)) {
return desired.toISOString();
}
// Adjust to nearest valid time
if (desired < range.earliest) {
return range.earliest.toISOString();
}
if (desired > range.latest) {
return range.latest.toISOString();
}
throw new Error('Time adjustment failed');
}
// Handle timezone and format issues
function normalizeExportTime(timestamp) {
const date = new Date(timestamp);
if (isNaN(date.getTime())) {
throw new Error('Invalid timestamp: ' + timestamp);
}
return date.toISOString();
}Time adjustment strategies:
- Use latest available time if desired time is in the future
- Use earliest available time if desired time is too old
- Add buffer (5-10 minutes) to avoid edge cases
- Always use UTC timezone for consistency
If you need to export older data, enable or extend PITR retention:
# Enable point-in-time recovery
aws dynamodb update-continuous-backups --table-name "MyTable" --point-in-time-recovery-specification PointInTimeRecoveryEnabled=true
# For longer retention, consider AWS Backup
aws backup create-backup-plan --backup-plan '{"BackupPlanName": "DynamoDB-LongTerm", "Rules": [{"RuleName": "DailyBackups", "TargetBackupVaultName": "Default", "ScheduleExpression": "cron(0 5 ? * * *)", "Lifecycle": {"DeleteAfterDays": 365}}]}'PITR limitations:
- Maximum retention: 35 days
- Cannot retroactively increase retention
- Must be enabled before you need to recover/export data
- Consider AWS Backup for longer retention needs
Build error handling and validation for export operations:
// Comprehensive export time validation
class ExportTimeValidator {
constructor(tableName, dynamodbClient) {
this.tableName = tableName;
this.client = dynamodbClient;
}
async validateExportTime(desiredTime) {
const response = await this.client.describeContinuousBackups({
TableName: this.tableName
}).promise();
const pitr = response.ContinuousBackupsDescription.PointInTimeRecoveryDescription;
const earliest = new Date(pitr.EarliestRestorableDateTime);
const latest = new Date(pitr.LatestRestorableDateTime);
const time = new Date(desiredTime);
const now = new Date();
if (time > now) {
throw new Error('ExportTime is in the future');
}
if (time < earliest) {
throw new Error('ExportTime is older than earliest restorable time');
}
const effectiveLatest = latest < now ? latest : now;
if (time > effectiveLatest) {
throw new Error('ExportTime is newer than latest restorable time');
}
return time.toISOString();
}
}Robust handling features:
- Cache PITR range to reduce API calls
- Automatic time adjustment when validation fails
- Fallback mechanisms for edge cases
- Comprehensive error logging
Implement monitoring and proactive checks:
# Create CloudWatch alarm for PITR issues
aws cloudwatch put-metric-alarm --alarm-name "DynamoDB-PITR-Health-MyTable" --comparison-operator "GreaterThanThreshold" --evaluation-periods 1 --metric-name "UserErrors" --namespace "AWS/DynamoDB" --period 300 --statistic "Sum" --threshold 0 --alarm-description "Alarm for DynamoDB PITR-related errors"
# Create CloudWatch Events rule for daily PITR check
aws events put-rule --name "Daily-PITR-Check" --schedule-expression "cron(0 8 ? * * *)" --state "ENABLED" --description "Daily check of DynamoDB PITR health"Monitoring strategy:
- Daily PITR health checks
- CloudWatch alarms for export failures
- Retention period warnings
- Automated alerting for critical issues
## DynamoDB Point-in-Time Recovery Deep Dive
### PITR Architecture and Limitations:
How PITR Works:
1. Continuous backups: DynamoDB continuously backs up table data
2. Incremental changes: Stores changes at 1-second granularity
3. Retention window: Default 35 days, configurable from 1 to 35 days
4. Restore points: Can restore to any second within retention window
ExportTime Validation Rules:
1. Minimum age: ExportTime must be ≥ table creation time
2. Maximum age: ExportTime must be within PITR retention period
3. Future restriction: ExportTime cannot be in the future
4. PITR enabled: Table must have PITR enabled at requested time
5. Time granularity: Supported to the second (milliseconds truncated)
### ExportTime Calculation Best Practices:
Always Use UTC:
// Good - ISO 8601 with UTC
const goodTime = '2025-02-01T12:00:00Z';
// Convert local time to UTC
const localTime = new Date('2025-02-01T12:00:00');
const utcTime = localTime.toISOString();Add Time Buffers:
// Add buffer to avoid edge cases
function getSafeExportTime(desiredTime) {
const time = new Date(desiredTime);
const now = new Date();
if (time > now) {
time = new Date(now);
}
time.setMinutes(time.getMinutes() - 5);
return time.toISOString();
}### Error Recovery Patterns:
When InvalidExportTimeException Occurs:
1. Immediate retry with adjusted time:
- Subtract 1-5 minutes from desired time
- Use current time if future time was specified
- Use earliest restorable if time is too old
2. Fallback strategies:
- Use latest successful export if available
- Implement incremental export pattern
- Switch to AWS Backup for older data
### Alternative Approaches:
When PITR Doesn't Meet Needs:
1. AWS Backup for DynamoDB:
- Longer retention (up to years)
- Cross-region backup
- Legal hold capabilities
2. DynamoDB Streams + Lambda:
- Real-time data export
- Custom transformation logic
- Multiple destination support
Migration Strategy:
- Use PITR for recent data (last 35 days)
- Use AWS Backup for archival data
- Implement hybrid approach based on data age