From af4ef4ec04551229f59fbc4daec211a20bb0189c Mon Sep 17 00:00:00 2001 From: bbiao Date: Mon, 14 Dec 2020 17:31:10 +0800 Subject: [PATCH] client/v3: clear auth token when encounter ErrInvalidAuthToken Old etcdserver which have not apply pr of #12165 will check auth token even if the request is an Authenticate request. If the client has a invalid auth token, it will not able to update it's token, since the Authenticate has a invalid auth token. This fix clear the auth token when encounter an ErrInvalidAuthToken to talk with old version etcd servers. Fix #12385 with #12165 and #12264 --- client/v3/retry_interceptor.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/client/v3/retry_interceptor.go b/client/v3/retry_interceptor.go index ff9ad601a..371c85800 100644 --- a/client/v3/retry_interceptor.go +++ b/client/v3/retry_interceptor.go @@ -74,6 +74,12 @@ func (c *Client) unaryClientInterceptor(logger *zap.Logger, optFuncs ...retryOpt continue } if callOpts.retryAuth && rpctypes.Error(lastErr) == rpctypes.ErrInvalidAuthToken { + // clear auth token before refreshing it. + // call c.Auth.Authenticate with an invalid token will always fail the auth check on the server-side, + // if the server has not apply the patch of pr #12165 (https://github.com/etcd-io/etcd/pull/12165) + // and a rpctypes.ErrInvalidAuthToken will recursively call c.getToken until system run out of resource. + c.authTokenBundle.UpdateAuthToken("") + gterr := c.getToken(ctx) if gterr != nil { logger.Warn( @@ -240,6 +246,9 @@ func (s *serverStreamingRetryingStream) receiveMsgAndIndicateRetry(m interface{} return true, err } if s.callOpts.retryAuth && rpctypes.Error(err) == rpctypes.ErrInvalidAuthToken { + // clear auth token to avoid failure when call getToken + s.client.authTokenBundle.UpdateAuthToken("") + gterr := s.client.getToken(s.ctx) if gterr != nil { s.client.lg.Warn("retry failed to fetch new auth token", zap.Error(gterr))