Outbound Campaign API 409 Conflict during Terraform Apply

I’m completely stumped as to why the genesyscloud_outbound_campaign resource fails with a 409 Conflict error during terraform apply. The provider version is 1.46.1 in the AU1 region. The error indicates a duplicate campaign name, but the HCL configuration uses dynamic naming via ${var.env}-${var.project} variables. The previous state was destroyed manually via CLI before this run.

Is there a race condition in the API cleanup process?

You need to check the WFM schedule adherence logs for any lingering state that might be blocking the outbound resource creation. While this looks like a pure Outbound issue, I’ve seen cross-module conflicts when agents are assigned to both scheduled queues and outbound campaigns simultaneously. The 409 Conflict often masks a deeper resource lock rather than just a name duplicate.

Try adding a depends_on block in your Terraform config to ensure the WFM schedule publish completes before the outbound campaign initializes. This forces the API to process the agent availability state first.

Requirement Detail
Provider Version >= 1.46.1
Dependency genesyscloud_wfm_schedule
Region AU1

Also, verify that the dynamic variable interpolation isn’t caching an old value in the state file. Run terraform refresh to sync with the actual API state before applying again. The manual destroy via CLI might have left orphaned records in the database that the provider doesn’t see immediately.

This happens because the asynchronous nature of resource deletion in the Genesys Cloud API. Even if the state file shows the resource as destroyed, the backend database might still hold a soft-deleted record for a few minutes. The 409 Conflict error appears because the API sees the name as active during that brief window. To fix this, add a depends_on meta-argument in your Terraform configuration to wait for a dependent resource to fully initialize, or use the lifecycle { ignore_changes = [name] } block if the name stability is not critical. Another approach is to implement a retry mechanism in your CI/CD pipeline that waits for the 409 to resolve before re-applying. This ensures the API has finished its cleanup process. It is a common issue with bulk operations and Terraform, especially in regions with higher latency.

You need to look at the API throughput limits rather than just the Terraform state. The 409 conflict often happens when the delete request hasn’t fully propagated through the regional load balancers before the create request hits the same shard. In my load tests from Singapore, I see this pattern when blasting campaign creation requests without proper pacing. The platform API has strict rate limits for outbound resources, and Terraform’s parallelism can easily trigger a 429 that gets masked as a 409 if the backend is in a transitional state.

Try adding a sleep or a retry logic with exponential backoff in your Terraform provider configuration. You can also check the API gateway logs for 429s preceding the 409. Here is a sample JMeter config snippet I use to simulate this race condition and verify the cleanup latency:

<ThreadGroup>
 <stringProp name="ThreadGroup.num_threads">50</stringProp>
 <stringProp name="ThreadGroup.ramp_time">1</stringProp>
 <elementProp name="HTTPSamplerProxy">
 <stringProp name="HTTPSampler.method">DELETE</stringProp>
 <stringProp name="HTTPSampler.path">/api/v2/outbound/campaigns/${campaignId}</stringProp>
 </elementProp>
 <elementProp name="ConstantTimer">
 <stringProp name="ConstantTimer.delay">2000</stringProp> <!-- Wait for propagation -->
 </elementProp>
</ThreadGroup>

The documentation suggests that resource deletion is asynchronous. When you destroy state via CLI, the local state file updates immediately, but the Genesys Cloud backend might still be processing the deletion. This creates a window where the name is still reserved. Adding a depends_on block helps, but it doesn’t wait for the actual API cleanup to finish. You might also want to check if your API token has the outbound:campaign scope, as insufficient permissions can sometimes cause weird conflict errors. Make sure you are not hitting the concurrent call volume limits for campaign creation either.