401 seems to be used to indicate an authentication failure whereas 403 for an authorization failure (which means authentication succeeded?) In case of an oauth flow if I try to authenticate with an expired token what is the right error code that prompts the client to refresh the token and try again?
A 401. The 401 vs 403 confusion is not new. See some discussion in a w3.org email here: https://lists.w3.org/Archives/Public/ietf-http-wg/2008AprJun/0418.html, though the cited RFC 2616 has been obsoleted.
Re 401, see https://tools.ietf.org/html/rfc7235#section-3.1
Re 403, see https://tools.ietf.org/html/rfc7231#section-6.5.3
From the 401 description, though "valid" is up for interpretation:
The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource.
But even more relevant, see RFC 6750 regarding Bearer Token authentication, Section 3, last paragraph. https://tools.ietf.org/html/rfc6750#section-3
And in response to a protected resource request with an authentication attempt using an expired access token:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example",
error="invalid_token",
error_description="The access token expired"