What the message looks like
OneLogin_Saml2_ValidationError: Invalid audience for this Response (expected 'https://cloud.example.com/apps/user_saml/saml/metadata', got 'https://cloud.example.com')Common causes
- The Entity ID (audience) configured in the IdP differs from the one in the service provider, often by a trailing slash,
httpagainsthttps, or the metadata URL against a plain name. - The IdP application was created for another app or environment, for example test against production, and keeps the old value.
- The service provider builds its Entity ID from the request URL, and behind a reverse proxy that URL differs from the public one.
- The IdP metadata was imported before the Entity ID was changed and never refreshed.
Check
- What audience does the response carry? (paste the decoded response in a file)
base64 -d saml-response.b64 | xmllint --format - | grep -i -A2 Audience - What Entity ID does the service provider publish?
curl -s https://cloud.example.com/index.php/apps/user_saml/saml/metadata | grep -o 'entityID="[^"]*"' - What is stored in the Nextcloud SAML settings?
- Does Nextcloud know its public protocol?
sudo -u www-data php occ config:system:get overwriteprotocol
Fix
- Pick one exact Entity ID and make both sides identical, character for character, including case and the trailing slash.
- Enter that value as the audience or Entity ID of the application in the IdP, and as the service provider Entity ID in the app.
- Behind a proxy, set
occ config:system:set overwriteprotocol --value=httpsand the right host, so the app builds the public address. - Re-import or re-save the IdP metadata and the service provider metadata after any change.
- Log in again in a private window and decode a new response to confirm that the audience now matches.
FAQ
Is this the same as a clock skew error?
No. A clock error shows NotBefore or NotOnOrAfter and is about time. Invalid audience is about names only, and clocks can be perfect.
Should the Entity ID be the metadata URL?
It can be, if both sides use the same. Many IdPs prefill the URL of the metadata, others use a plain name or a URN. What counts is that both sides carry the same string.