Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for OpenStack By James Joyner IV · · 10 min read

OpenStack Error Guide: 'Application credentials cannot request a scope' Keystone Auth Failure

Fix the Keystone 'Application credentials cannot request a scope' error: strip OS_PROJECT scope vars, fix clouds.yaml v3applicationcredential auth, recreate app creds.

  • #openstack
  • #troubleshooting
  • #errors
  • #keystone

Overview

A Keystone application credential is permanently bound to the project (and roles) of whoever created it. You authenticate with the credential’s ID and secret only — you do not get to pick a project or domain at auth time, because the scope was fixed when the credential was created. When your environment or clouds.yaml also passes project/domain scope variables, Keystone sees a conflicting scope request and rejects the token with 400 Bad Request.

You will see this from the CLI or SDK:

Failed to validate token (HTTP 400): Application credentials cannot request a scope.

Or the more specific variant:

The request you have made requires authentication. (HTTP 401)
Application credentials cannot be used with a scope that differs from the one they were created with.

The fix is almost always to stop sending scope: remove OS_PROJECT_* / OS_DOMAIN_* from the environment, or fix the auth block in clouds.yaml so it carries only the credential id and secret.

Symptoms

  • openstack token issue or any command fails with Application credentials cannot request a scope.
  • A clouds.yaml cloud using auth_type: v3applicationcredential errors only when project vars are also set.
  • The same credential works from a clean shell but fails after sourcing a project RC file.
  • “Cannot change scope” appears when reusing one credential against a different project.
openstack token issue -c id -f value
Application credentials cannot request a scope. (HTTP 400)
env | grep -E '^OS_' | sort
OS_APPLICATION_CREDENTIAL_ID=4d2c...
OS_APPLICATION_CREDENTIAL_SECRET=********
OS_AUTH_TYPE=v3applicationcredential
OS_PROJECT_ID=9a8b7c...
OS_PROJECT_DOMAIN_NAME=Default

The trailing OS_PROJECT_* and OS_*_DOMAIN_* vars are the conflicting scope.

Common Root Causes

1. Project/domain scope vars left in the environment

An app credential RC file should only export the credential id, secret, auth URL, and OS_AUTH_TYPE. If a previous openrc (password auth) was sourced in the same shell, its OS_PROJECT_* vars linger and collide.

env | grep -E '^OS_(PROJECT|TENANT|DOMAIN|USER|USERNAME)' 
OS_PROJECT_NAME=admin
OS_USER_DOMAIN_NAME=Default

Any of these alongside an app credential triggers the scope conflict.

2. clouds.yaml carrying both app-cred and project keys

The v3applicationcredential auth type must not include project_id, project_name, project_domain_name, or user_domain_name. A clouds.yaml copied from a password cloud often keeps them.

openstack --os-cloud mycloud token issue 2>&1 | tail -1
grep -A8 'mycloud:' ~/.config/openstack/clouds.yaml
  mycloud:
    auth_type: v3applicationcredential
    auth:
      auth_url: https://keystone.example.com:5000/v3
      application_credential_id: 4d2c...
      application_credential_secret: ********
      project_id: 9a8b7c...        # <- remove this

The stray project_id makes the SDK request a scope the credential cannot grant.

3. Mixed auth_type vs. credential variables

OS_AUTH_TYPE is unset or set to password/v3token, but only app-credential variables are present (or vice versa). Keystone then tries password/token flow and misinterprets the scope.

echo "auth_type=$OS_AUTH_TYPE"
auth_type=

With app-cred vars present, OS_AUTH_TYPE must be v3applicationcredential.

4. Reusing one credential across projects

App credentials cannot “change scope”. Pointing a credential created in project A at project B (by changing OS_PROJECT_ID) yields Cannot change scope / cannot be used with a scope that differs.

openstack application credential show my-cred -c project_id -f value
9a8b7c...

That project_id is the only project the credential will ever serve; to work in another project, create a new credential there.

5. Expired, deleted, or wrong-role credential

A credential whose expires_at has passed, or that was deleted, returns 401; one whose underlying role assignment changed may fail to scope as expected. Restrictive access_rules can also block the call.

openstack application credential show my-cred -c expires_at -c roles -c unrestricted -f value
2026-01-01T00:00:00.000000
['reader']
False

An expired date or a too-narrow role set means the credential must be recreated.

6. Trust or federation scope interactions

For federated users or trust-delegated tokens, the effective scope is constrained by the trust/IdP mapping. Combining that with explicit project vars produces the same scope conflict.

openstack token issue -c project_id -f value 2>&1 | tail -1
Application credentials cannot request a scope.

Federated identities should rely on the credential’s own scope rather than passing project/domain.

Diagnostic Workflow

Step 1: Dump the OpenStack environment

env | grep -E '^OS_' | sort

Confirm only OS_AUTH_URL, OS_APPLICATION_CREDENTIAL_ID, OS_APPLICATION_CREDENTIAL_SECRET, OS_AUTH_TYPE, and identity API version remain. Any OS_PROJECT_* / OS_*_DOMAIN_* / OS_USERNAME is suspect.

Step 2: Strip the scope vars and retry from a clean shell

unset OS_PROJECT_ID OS_PROJECT_NAME OS_PROJECT_DOMAIN_NAME \
      OS_USER_DOMAIN_NAME OS_USERNAME OS_PASSWORD OS_TENANT_NAME
export OS_AUTH_TYPE=v3applicationcredential
openstack token issue -c id -f value

If the token issues now, the lingering scope vars were the cause.

Step 3: Validate clouds.yaml if using —os-cloud

grep -B1 -A10 'auth_type: v3applicationcredential' ~/.config/openstack/clouds.yaml

Ensure the auth: block has only auth_url, application_credential_id, and application_credential_secret. Delete any project_*/*_domain_* keys.

Step 4: Confirm the credential is valid and not expired

# Authenticate as the owning user (password creds) to inspect:
openstack application credential list -f value -c "ID" -c "Name" -c "Expires At"
openstack application credential show <NAME_OR_ID> -c project_id -c roles -c expires_at -c unrestricted -f value

A past expires_at, missing entry (deleted), or wrong project means you need a new credential.

Step 5: Check Keystone logs for the rejected request

# Kolla-Ansible
docker logs keystone 2>&1 | grep -i "application credential" | tail -10
# Traditional packages
sudo journalctl -u devstack@keystone --no-pager | grep -i "application credential" | tail -10
sudo tail -50 /var/log/keystone/keystone.log

Keystone logs the exact scope it received versus the credential’s fixed scope.

Example Root Cause Analysis

A CI job that uploads images starts failing with Application credentials cannot request a scope after the pipeline runner was “standardized” to source the operator’s admin-openrc.sh before the app-credential RC.

Dumping the environment shows the collision:

env | grep -E '^OS_' | sort
OS_APPLICATION_CREDENTIAL_ID=4d2c...
OS_APPLICATION_CREDENTIAL_SECRET=********
OS_AUTH_TYPE=v3applicationcredential
OS_PROJECT_DOMAIN_NAME=Default
OS_PROJECT_NAME=admin
OS_USERNAME=admin

The earlier admin-openrc.sh left OS_PROJECT_NAME, OS_PROJECT_DOMAIN_NAME, and OS_USERNAME exported. The app credential is bound to the ci-images project, so the request to scope to admin is rejected outright.

Fix: source the app-credential RC in a clean environment and stop sourcing the password RC in the same shell:

unset OS_PROJECT_NAME OS_PROJECT_DOMAIN_NAME OS_USERNAME OS_PASSWORD
source app-cred-openrc.sh
openstack token issue -c id -f value

The token issues against ci-images and the upload job succeeds.

Prevention Best Practices

  • Generate app-credential RC files with only OS_AUTH_URL, OS_AUTH_TYPE=v3applicationcredential, OS_APPLICATION_CREDENTIAL_ID, OS_APPLICATION_CREDENTIAL_SECRET, and OS_IDENTITY_API_VERSION=3 — never project or domain vars.
  • Use one credential per project; treat “needs another project” as “create a new credential” since scope cannot change.
  • In clouds.yaml, keep v3applicationcredential clouds in their own entries with no project_*/*_domain_* keys, separate from password clouds.
  • Run pipelines in clean shells so a previously sourced password RC never bleeds OS_PROJECT_* into an app-cred run.
  • Set and monitor expires_at; rotate credentials before expiry and scope access_rules/roles to exactly what the automation needs.
  • For ad-hoc triage, the free incident assistant can map a Keystone scope rejection to the offending env var or clouds.yaml key. See more in OpenStack guides.

Quick Command Reference

# Inspect the current OpenStack environment
env | grep -E '^OS_' | sort

# Strip conflicting scope vars and retry
unset OS_PROJECT_ID OS_PROJECT_NAME OS_PROJECT_DOMAIN_NAME \
      OS_USER_DOMAIN_NAME OS_USERNAME OS_PASSWORD OS_TENANT_NAME
export OS_AUTH_TYPE=v3applicationcredential
openstack token issue -c id -f value

# Validate clouds.yaml app-cred block
grep -B1 -A10 'auth_type: v3applicationcredential' ~/.config/openstack/clouds.yaml

# Inspect the credential (as the owning user)
openstack application credential list
openstack application credential show <NAME_OR_ID> \
  -c project_id -c roles -c expires_at -c unrestricted -f value

# Recreate with correct roles/access_rules
openstack application credential create ci-uploader --role member

# Keystone logs
docker logs keystone 2>&1 | grep -i "application credential" | tail -10
sudo tail -50 /var/log/keystone/keystone.log

Conclusion

Application credentials cannot request a scope means you authenticated with an app credential while also asking Keystone for a project/domain scope the credential cannot grant — its scope is fixed at creation. The usual root causes:

  1. Leftover OS_PROJECT_* / OS_*_DOMAIN_* vars in the environment.
  2. A clouds.yaml v3applicationcredential block that still carries project/domain keys.
  3. A mismatched or unset OS_AUTH_TYPE.
  4. Reusing one credential against a different project (“cannot change scope”).
  5. An expired, deleted, or wrongly-scoped/role-restricted credential.
  6. Trust/federation scope interacting with explicit project vars.

Strip the scope from your environment or clouds.yaml first — authenticate with id and secret alone — and recreate the credential in the right project when the scope genuinely needs to differ.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.