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 issueor any command fails withApplication credentials cannot request a scope.- A
clouds.yamlcloud usingauth_type: v3applicationcredentialerrors 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, andOS_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, keepv3applicationcredentialclouds in their own entries with noproject_*/*_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 scopeaccess_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:
- Leftover
OS_PROJECT_*/OS_*_DOMAIN_*vars in the environment. - A
clouds.yamlv3applicationcredentialblock that still carries project/domain keys. - A mismatched or unset
OS_AUTH_TYPE. - Reusing one credential against a different project (“cannot change scope”).
- An expired, deleted, or wrongly-scoped/role-restricted credential.
- 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.
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.