DryRunOperation
AWS DryRunOperation means a request submitted with the dry-run flag would have succeeded if executed for real. The operation was not performed, no resources were created or modified, but the IAM permissions and request parameters were valid.
Last reviewed: March 29, 2026|Editorial standard: source-backed technical guidance
What Does Dry Run Operation Mean?
DryRunOperation is a success signal disguised as an error. AWS returns HTTP 412 with this error code to confirm that the dry-run check passed. The request had valid credentials, sufficient IAM permissions, and correct parameters. Callers that treat DryRunOperation as a failure will incorrectly report that a valid operation failed when it actually would have succeeded.
Common Causes
- -Application or script uses dry-run to validate IAM permissions before executing a destructive operation, receives DryRunOperation, and incorrectly treats it as a failure instead of a permission confirmation.
- -Infrastructure automation tool sends dry-run requests to preview changes but does not handle DryRunOperation as a success signal, causing the preview to report false failures.
- -Developer testing a new IAM policy uses dry-run to verify permissions but the error handling code catches DryRunOperation alongside real errors and masks the successful permission check.
How to Fix Dry Run Operation
- 1Catch DryRunOperation explicitly in error handling code and treat it as a success. Log "dry-run succeeded, permissions are valid" rather than reporting it as a failure.
- 2Separate DryRunOperation handling from real error handling. Use a dedicated branch that confirms the permission check passed and proceeds to execute the real operation if desired.
- 3If the script reports DryRunOperation as a failure, add an explicit check before the generic error handler that intercepts this specific code and converts it to a success path.
Step-by-Step Diagnosis for Dry Run Operation
- 1Confirm the request was sent with DryRun: true. DryRunOperation only appears on dry-run requests and always means the operation would have succeeded.
- 2Check whether the error handling code treats all exceptions as failures. DryRunOperation must be caught separately and handled as a success signal, not an error.
- 3Verify the intended workflow. If the goal is to check permissions and then execute, add logic to retry without dry-run after receiving DryRunOperation.
- 4Distinguish DryRunOperation from UnauthorizedOperation. UnauthorizedOperation means the dry-run failed because permissions are insufficient, while DryRunOperation means permissions are valid.
Dry-Run Success vs Failure Distinction
- -Understand the two possible outcomes of a dry-run request. DryRunOperation means the operation would succeed and permissions are valid, while UnauthorizedOperation means the operation would fail due to insufficient IAM permissions (example: a script checking whether an IAM role can terminate EC2 instances should report success on DryRunOperation and report a permission error on UnauthorizedOperation).
- -Check whether the automation framework being used has built-in dry-run support. AWS CDK, Terraform plan, and CloudFormation change sets all have their own preview mechanisms that do not use EC2 dry-run and do not return DryRunOperation (example: using Terraform plan instead of EC2 dry-run for infrastructure previews avoids DryRunOperation entirely and provides a richer change preview).
Permission Validation Workflow
- -Use dry-run as a pre-flight permission check before destructive operations. Send the request with DryRun: true, handle DryRunOperation as confirmation to proceed, then resend with DryRun: false to execute (example: pre-flight check before bulk instance termination confirms the IAM role has ec2:TerminateInstances permission without actually terminating anything).
- -Note that dry-run only validates IAM permissions and basic parameter syntax. It does not validate resource state, quotas, or availability zone capacity, so a successful DryRunOperation does not guarantee the real operation will succeed (example: DryRunOperation confirms permission to launch an instance but the real launch may still fail with InsufficientInstanceCapacity).
Implementation Examples
# Dry-run permission check - does not terminate instances
aws ec2 terminate-instances \
--instance-ids i-1234567890abcdef0 \
--dry-run
# Success output (permissions valid):
# An error occurred (DryRunOperation) when calling the TerminateInstances operation:
# Request would have succeeded, but DryRun flag is set.
# Failure output (insufficient permissions):
# An error occurred (UnauthorizedOperation) when calling the TerminateInstances operation:
# You are not authorized to perform this operation.import { EC2Client, TerminateInstancesCommand } from '@aws-sdk/client-ec2';
const client = new EC2Client({ region: 'us-east-1' });
async function checkTerminatePermission(instanceIds) {
try {
await client.send(new TerminateInstancesCommand({
InstanceIds: instanceIds,
DryRun: true,
}));
} catch (err) {
if (err.name === 'DryRunOperation') {
console.log('Permission check passed - allowed to terminate instances');
return true;
}
if (err.name === 'UnauthorizedOperation') {
console.error('Permission check failed - not allowed to terminate instances');
return false;
}
throw err;
}
}
if (await checkTerminatePermission(instanceIds)) {
await client.send(new TerminateInstancesCommand({ InstanceIds: instanceIds }));
}import boto3
from botocore.exceptions import ClientError
client = boto3.client('ec2', region_name='us-east-1')
def check_permission(instance_ids):
try:
client.terminate_instances(
InstanceIds=instance_ids,
DryRun=True,
)
except ClientError as e:
code = e.response['Error']['Code']
if code == 'DryRunOperation':
print('Permission check passed - allowed to terminate instances')
return True
if code == 'UnauthorizedOperation':
print('Permission check failed - not allowed to terminate instances')
return False
raise
def terminate_with_preflight(instance_ids):
if check_permission(instance_ids):
client.terminate_instances(InstanceIds=instance_ids, DryRun=False)
print(f'Terminated {len(instance_ids)} instances')How to Verify the Fix
- -Re-run the dry-run request and confirm DryRunOperation is caught as a success signal and the script reports permissions as valid.
- -Execute the real operation without dry-run and confirm it completes successfully. DryRunOperation guarantees permissions are valid but not that the operation will succeed for other reasons.
- -Test the UnauthorizedOperation path by using a role without the required permission and confirm the script correctly reports a permission failure.
How to Prevent Recurrence
- -Add explicit DryRunOperation handling to all AWS API clients used in automation scripts and document it as a special success case in code comments so future engineers do not accidentally convert it back to an error.
- -Build a permission validation utility that wraps dry-run calls and returns a typed result, for example dryRunSucceeded, dryRunFailed, or realError, rather than relying on raw exception handling that conflates DryRunOperation with actual failures.
- -Include DryRunOperation and UnauthorizedOperation handling in CI test suites that verify IAM permission checks work correctly before deploying automation scripts to production.
Pro Tip
- -use dry-run as a mandatory pre-flight step for any automation that terminates, stops, or modifies EC2 instances in bulk. A DryRunOperation confirmation before the real operation adds negligible latency but prevents permission errors from being discovered mid-execution when some instances have already been affected.
Decision Support
Compare Guide
401 Unauthorized vs 403 Forbidden: Auth vs Access Denied
Fix 401 Unauthorized vs 403 Forbidden by separating authentication failures from authorization denials, then apply the right login or permission fix fast.
Compare Guide
403 Forbidden vs 404 Not Found: When to Hide Resources
Use 403 for explicit access denial, or 404 to conceal resource existence when security policy requires reducing endpoint and object enumeration risk.
Playbook
Authorization Denial Playbook (403 / AccessDenied / PERMISSION_DENIED)
Use this playbook to triage policy-based access denials after authentication succeeds, isolate the deny layer, and apply least-privilege remediation safely.
Official References
Provider Context
This guidance is specific to AWS services. Always validate implementation details against official provider documentation before deploying to production.