From 4ebbf59d2ec6518564f6bfc0799082d0621b2ec5 Mon Sep 17 00:00:00 2001 From: Corey Christous Date: Sat, 31 Jan 2026 08:55:40 -0500 Subject: [PATCH] fix: retry log push immediately after token refresh Previously, when a log push request received a 401 Unauthorized response, the agent would refresh the token but then return an error, causing a spurious "Error pushing logs: 401 Unauthorized" message to be logged. The next push would succeed with the new token, but the error log was confusing and happened every hour when tokens expired. This change: - Extracts the HTTP request logic into a separate sendLogRequest function - Stores the buffer contents before sending so they can be reused on retry - After refreshing the token, immediately retries the request instead of returning an error - Limits retry to once to avoid infinite loops The result is cleaner logs: instead of seeing "Successfully refreshed token" followed by "Error pushing logs: 401 Unauthorized", users will see "Retrying log push with refreshed token..." and the request succeeds. --- pkg/eventlogger/httpbackend.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/pkg/eventlogger/httpbackend.go b/pkg/eventlogger/httpbackend.go index 3250c6a..b056a40 100644 --- a/pkg/eventlogger/httpbackend.go +++ b/pkg/eventlogger/httpbackend.go @@ -176,8 +176,16 @@ func (l *HTTPBackend) newRequest() error { } log.Infof("Pushing next batch of logs with %d log events...", (nextStartFrom - l.startFrom)) + + // Store buffer contents so we can retry after token refresh + bufferBytes := buffer.Bytes() + + return l.sendLogRequest(bufferBytes, nextStartFrom, false) +} + +func (l *HTTPBackend) sendLogRequest(bufferBytes []byte, nextStartFrom int, isRetry bool) error { url := fmt.Sprintf("%s?start_from=%d", l.config.URL, l.startFrom) - request, err := http.NewRequest("POST", url, buffer) + request, err := http.NewRequest("POST", url, bytes.NewReader(bufferBytes)) if err != nil { return err } @@ -206,16 +214,21 @@ func (l *HTTPBackend) newRequest() error { return errors.New("no more space available for logs - stopping") // The token issued for the agent expired. - // Try to refresh the token and try again. - // Here, we only update the token, and we let the caller do the retrying. + // Try to refresh the token and retry immediately. case http.StatusUnauthorized: + // Only retry once to avoid infinite loops + if isRetry { + return fmt.Errorf("request to %s failed after token refresh: %s", url, response.Status) + } + newToken, err := l.config.RefreshTokenFn() if err != nil { return err } l.config.Token = newToken - return fmt.Errorf("request to %s failed: %s", url, response.Status) + log.Infof("Retrying log push with refreshed token...") + return l.sendLogRequest(bufferBytes, nextStartFrom, true) // something else went wrong default: