Every request comes back 401 Unauthorized.
The 401 response carries a WWW-Authenticate: Bearer ...,
resource_metadata="..." header. That header is informative: it
names the resource-metadata URL the client should re-fetch to
re-discover the AS, and (if the validation reached that point)
carries an error_description naming the specific failure.
OAuthAsIniFile was deleted or overwritten — common after a
redeploy when OAuthAsIniFile was left at its
WAR-tree-internal default. Recovery: the client redoes the full
OAuth login flow. Prevention: set OAuthAsIniFile to an
absolute path outside the webapp (see Installation).
OAuthAuthorizationServer is unset in
application.ini, the entire OAuth path returns 500 (not
401) with “OAuth resource-server is not configured.” Check
journalctl -u ownsona.service.
iss doesn’t
match OAuthAuthorizationServer. Happens when you have
multiple environments (staging, prod) and a client is talking to
one with a token issued by the other.
Without a token, you should get a 401 with a proper challenge header:
curl -sS -i -X POST https://<host>/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'
Look for the WWW-Authenticate: Bearer ... header. If the
response is 500 instead of 401, the OAuth resource server isn’t
configured. If it’s 200 (unauthenticated success), the AS isn’t
enabled but the server didn’t refuse the request — check
OAuthAuthorizationServer in application.ini.
With a valid token (obtained via any OAuth-capable MCP client):
curl -sS -X POST https://<host>/mcp \
-H "Authorization: Bearer $OWNSONA_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'
200 with a server-info payload means the OAuth path is
working end-to-end.