This error occurs when attempting to restore a DynamoDB table from a point-in-time backup, but Point-in-Time Recovery (PITR) is not enabled on the source table. PITR must be explicitly enabled to create continuous backups and allow restoration to any point in time within the retention period.
The PointInTimeRecoveryUnavailableException error in DynamoDB indicates that you're trying to perform a point-in-time restore operation on a table that doesn't have Point-in-Time Recovery (PITR) enabled. Point-in-Time Recovery is an optional DynamoDB feature that provides continuous backups of your table data. When enabled, it allows you to restore your table to any point in time within the last 35 days (the retention period). This error occurs because: 1. **PITR is disabled by default** - You must explicitly enable it for each table 2. **Restore operations require PITR** - You can only restore from points in time when PITR was active 3. **No backup exists** - Without PITR, there are no continuous backups to restore from This is a client-side error (HTTP 400) that prevents the restore operation from proceeding until PITR is properly configured.
First, verify whether Point-in-Time Recovery is enabled on your table:
# Using AWS CLI
aws dynamodb describe-continuous-backups --table-name YourTableName --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription'
# Expected output if PITR is enabled:
# {
# "PointInTimeRecoveryStatus": "ENABLED",
# "EarliestRestorableDateTime": "2025-12-10T10:30:00.000Z",
# "LatestRestorableDateTime": "2025-12-12T10:30:00.000Z"
# }
# If PITR is disabled, you'll see:
# {
# "PointInTimeRecoveryStatus": "DISABLED"
# }Key points:
- Check the PointInTimeRecoveryStatus field
- If status is DISABLED, you need to enable PITR before restoring
- Note the EarliestRestorableDateTime and LatestRestorableDateTime to know your restore window
If PITR is disabled, enable it on the source table:
# Enable PITR using AWS CLI
aws dynamodb update-continuous-backups --table-name YourTableName --point-in-time-recovery-specification 'PointInTimeRecoveryEnabled=true'
# Verify it's enabled
aws dynamodb describe-continuous-backups --table-name YourTableName --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription.PointInTimeRecoveryStatus'
# Should return "ENABLED"Important notes:
- Enabling PITR doesn't require downtime
- There's additional cost for PITR (based on table size and backup storage)
- It takes a few minutes for PITR to become active
- Once enabled, backups are continuous and automatic
After enabling PITR, wait for it to become fully active and create restore points:
# Check PITR status until it shows ENABLED with restore times
while true; do
result=$(aws dynamodb describe-continuous-backups --table-name YourTableName --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription')
status=$(echo $result | jq -r '.PointInTimeRecoveryStatus')
earliest=$(echo $result | jq -r '.EarliestRestorableDateTime // empty')
if [[ "$status" == "ENABLED" && -n "$earliest" ]]; then
echo "PITR is active. Earliest restore time: $earliest"
break
fi
echo "Waiting for PITR to become active... (status: $status)"
sleep 30
doneTiming considerations:
- PITR typically becomes active within 1-2 minutes
- The first restore point is created shortly after activation
- You can only restore to points in time after PITR was enabled
- Retention period is 35 days from the current time
Once PITR is enabled and active, you can perform the restore:
# Restore table to a specific point in time
aws dynamodb restore-table-from-point-in-time --source-table-name YourTableName --target-table-name YourTableName-restored --restore-date-time "2025-12-12T10:30:00.000Z" --use-latest-restorable-time
# Using --use-latest-restorable-time to restore to the latest possible time
aws dynamodb restore-table-from-point-in-time --source-table-name YourTableName --target-table-name YourTableName-latest --use-latest-restorable-time
# Monitor restore progress
aws dynamodb describe-table --table-name YourTableName-restored --query 'Table.TableStatus'Restore options:
- Specify exact timestamp with --restore-date-time
- Use --use-latest-restorable-time for most recent backup
- Restore to a new table name (required)
- Restore maintains original table settings (capacity mode, encryption, etc.)
To prevent this error in the future, enable PITR by default for critical tables:
# Enable PITR during table creation
aws dynamodb create-table --table-name NewCriticalTable --attribute-definitions 'AttributeName=id,AttributeType=S' --key-schema 'AttributeName=id,KeyType=HASH' --billing-mode PAY_PER_REQUEST --point-in-time-recovery-specification 'PointInTimeRecoveryEnabled=true'
# Using CloudFormation (YAML)
Resources:
MyTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: MyTable
# ... other properties
PointInTimeRecoverySpecification:
PointInTimeRecoveryEnabled: true
# Using Terraform
resource "aws_dynamodb_table" "example" {
name = "example"
# ... other attributes
point_in_time_recovery {
enabled = true
}
}Best practices:
- Enable PITR for all production tables
- Consider enabling via Infrastructure as Code (IaC)
- Document PITR status in your runbooks
- Include PITR checks in your deployment pipelines
Add proper error handling in your code to gracefully handle PITR unavailable errors:
// AWS SDK v3 for JavaScript
import { DynamoDBClient, RestoreTableFromPointInTimeCommand, DescribeContinuousBackupsCommand } from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({ region: 'us-east-1' });
async function restoreTableWithFallback(sourceTable, targetTable, restoreTime) {
try {
const command = new RestoreTableFromPointInTimeCommand({
SourceTableName: sourceTable,
TargetTableName: targetTable,
RestoreDateTime: restoreTime
});
return await client.send(command);
} catch (error) {
if (error.name === 'PointInTimeRecoveryUnavailableException') {
console.error('PITR not enabled on ' + sourceTable + '. Checking status...');
// Check PITR status
const describeCmd = new DescribeContinuousBackupsCommand({
TableName: sourceTable
});
const backupInfo = await client.send(describeCmd);
const pitrStatus = backupInfo.ContinuousBackupsDescription?.PointInTimeRecoveryDescription?.PointInTimeRecoveryStatus;
if (pitrStatus === 'DISABLED') {
console.error('PITR is disabled. You need to enable it first.');
// Optionally: Automatically enable PITR here
// Or provide instructions to the user
}
throw new Error('Cannot restore: PITR is ' + (pitrStatus || 'not configured'));
}
throw error;
}
}Error handling strategies:
- Catch specific exception types
- Provide clear error messages with remediation steps
- Consider automated remediation for non-production environments
- Log PITR status for audit purposes
## Point-in-Time Recovery Deep Dive
### How PITR Works:
1. Continuous Backups: PITR maintains incremental backups every second
2. 35-Day Retention: Backups are kept for 35 days (configurable via AWS Backup)
3. No Performance Impact: PITR operates without affecting table performance
4. Encryption: Backups inherit the table's encryption settings
### Cost Considerations:
- PITR Pricing: Charged per GB-month of backup storage
- Restore Operations: No additional charge for restore operations
- Storage Calculation: Based on size of changed items, not full table size
### Retention Period Management:
- Default retention is 35 days
- Can extend retention using AWS Backup
- AWS Backup allows retention policies up to years
- Consider compliance requirements (GDPR, HIPAA, etc.)
### Cross-Region Considerations:
- PITR is region-specific
- For cross-region disaster recovery, use DynamoDB Global Tables
- Global Tables have separate PITR configurations per region
- Restore operations are regional
### Integration with AWS Backup:
For longer retention or more sophisticated backup policies, use AWS Backup to create backup plans with custom retention policies.
### Monitoring and Alerts:
Set up CloudWatch alarms for PITR status to monitor when PITR is disabled on critical tables.
### Common Pitfalls:
1. Assuming PITR is enabled by default - It's opt-in
2. Restoring outside retention period - Check EarliestRestorableDateTime
3. Not waiting for PITR activation - Enable, then wait before restoring
4. Forgetting cross-region considerations - PITR is per-region
5. Ignoring cost implications - Monitor backup storage costs
### Best Practices:
1. Enable PITR for all production tables via Infrastructure as Code
2. Document restore procedures in runbooks
3. Test restore operations regularly as part of DR drills
4. Monitor PITR status with CloudWatch alarms
5. Consider AWS Backup for longer retention requirements
6. Train team members on PITR capabilities and limitations
ImportConflictException: There was a conflict when attempting to import to the table
How to fix 'ImportConflictException: There was a conflict when attempting to import to the table' in DynamoDB
ResourceNotFoundException: Requested resource not found
How to fix "ResourceNotFoundException: Requested resource not found" in DynamoDB
TrimmedDataAccessException: The requested data has been trimmed
How to fix "TrimmedDataAccessException: The requested data has been trimmed" in DynamoDB Streams
GlobalTableNotFoundException: Global Table not found
How to fix "GlobalTableNotFoundException: Global Table not found" in DynamoDB
InvalidExportTimeException: The specified ExportTime is outside of the point in time recovery window
How to fix "InvalidExportTimeException: The specified ExportTime is outside of the point in time recovery window" in DynamoDB