---
id: SAIFTRBL0010
moved_from:
  - guides/troubleshooting/okta-app-oauth-label-prefix-collision.md
title: "Terraform apply fails with 'no OAuth application found with the provided label' even though the Okta app exists"
description: The okta_app_oauth data source asks Okta for a single result from a startsWith search, so an app whose label is a prefix of another app's label can lose the only slot and fail the lookup.
tags:
  - troubleshooting
  - terraform
  - authentication
---
# Terraform apply fails with "no OAuth application found with the provided label" even though the Okta app exists

**One-sentence summary:** the `okta_app_oauth` data source's `label` argument runs a `limit=1` prefix search sorted by creation date, so an older app whose label starts with yours takes the only result slot and the exact-label check then fails.

---

## 🚨 Symptom

The `Deploy api_infra (terraform)` job fails during `🚀 Terraform Apply`:

```text
Error: no OAuth application found with the provided label: clm-api-proc-claim

  with module.saif-appservices.module.external_identity.data.okta_app_oauth.api_app,
  on ../saif-external-identity/main.tf line <n>, in data "okta_app_oauth" "api_app":
```

The app plainly exists. The `auth_ext_okta_client` stage in the same build succeeded and created it, and `data.okta_auth_server.api_app` in the same plan resolves against the same tenant with the same credentials.

---

## 📌 Applies to

| Aspect | Value |
| ------ | ----- |
| **Component** | `external-identity` module, `data.okta_app_oauth.api_app` |
| **Forge versions** | `saif-appservices` < 3.9.2 |
| **Provider** | `okta/okta`, all versions through 6.11.0 |
| **Environments** | Production first — non-prod labels carry an `-np` suffix, which makes the search term more selective |

---

## 🧠 Cause

This is not a propagation delay, a permissions problem, or a missing app.

The provider implements the singular data source's `label` argument as a `limit=1` query against Okta's List Applications API, then exact-compares only that single result:

```go
req := client.ApplicationAPI.ListApplications(ctx).Limit(1)
if q := filters.GetQ(); q != "" { req = req.Q(q) }
...
if filters.Label != "" && app.GetLabel() != filters.Label {
    return diag.Errorf("no OAuth application found with the provided label: %s", filters.Label)
}
```

Okta treats `q` as a case-insensitive **startsWith** match over both `name` and `label`, and returns results **sorted by creation date**. So if any other app's label begins with yours, and that app was created first, it occupies the one available slot, the exact-label comparison fails, and the lookup errors out.

`clm-api-proc-claim` hit this because `clm-api-proc-claimintake` already existed in the same tenant. Whether a given service fails depends on app creation order in the org, not on its Terraform configuration, so a workspace can start failing without anything in the config changing.

Tracked upstream as [okta/terraform-provider-okta#2847](https://github.com/okta/terraform-provider-okta/issues/2847). The generic `okta_app` data source was fixed for exactly this bug in #1111/#1115, but the fix was never propagated to `okta_app_oauth` or `okta_app_saml`.

### Telling this apart from a genuinely missing app

The provider emits two different error strings, and the distinction is the whole diagnosis:

| Error text | Meaning |
| ---------- | ------- |
| `no OAuth application found with provided filter: <filters>` | Zero results came back. The app really is missing, inactive, or in another tenant. |
| `no OAuth application found with the provided label: <label>` | A result **was** returned but its label didn't match. The app exists; another app won the slot. |

If you see the second form, do not rerun the stage hoping it settles. It is deterministic and will fail again.

---

## ✅ Fix

Upgrade the consuming service to `saif-appservices` 3.9.2 or later, then re-run the deploy:

```hcl
module "saif-appservices" {
  source  = "app.terraform.io/SAIFCorp/saif-apiservice/azure"
  version = "~> 3.9.2"
}
```

3.9.2 resolves the API app in two steps instead of one — search with the plural `okta_apps` data source, which paginates the full result set, filter it for an exact label match, then look the app up by `id`:

```hcl
data "okta_apps" "api_app" {
  q           = local.okta_app_label
  active_only = true
}

data "okta_app_oauth" "api_app" {
  id = one(local.api_app_matches)
}
```

A `lifecycle.precondition` asserts that exactly one app matched, so a missing or ambiguous app now fails with a message naming the label instead of binding an arbitrary app.

If you need to confirm the collision before upgrading, list the apps Okta actually returns for your label:

```powershell
$label = "clm-api-proc-claim"
curl -s -H "Authorization: SSWS $env:OKTA_API_TOKEN" `
  "https://saif-external.okta.com/api/v1/apps?q=$label&limit=20" |
  ConvertFrom-Json | Select-Object id, label, created
```

Any entry whose `label` starts with yours and has an earlier `created` timestamp is the app that took the slot.

---

## 🔬 Verify

Re-run the failed stage. The plan now reads both data sources and resolves the app by id:

```text
module.saif-appservices.module.external_identity.data.okta_apps.api_app: Refresh complete after 1s
 <= data "okta_app_oauth" "api_app" {
      + id = "0oawz83970ymRPEma5d7"
```

Confirm that `id` matches the `client_id` the `auth_ext_okta_client` stage logged when it created the app.

---

## 📚 Related

- [okta/terraform-provider-okta#2847](https://github.com/okta/terraform-provider-okta/issues/2847)
- [Terraform apply still fails with 409 RoleAssignmentExists after upgrading past 3.8.6](external-identity-role-assignment-tainted-after-fix.md)
