From a0db7729ce28a763c1b9a02a25a27786e0391fee Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Fri, 31 Jul 2026 14:10:42 -0400 Subject: [PATCH] fix: demote non-gRPC auth error log from Error to Debug A client failing to authenticate is a client-side condition, not a server fault. Both the Connect and gRPC auth middlewares logged every non-gRPC error from the authenticator at Error level, which floods logs and lights up error-rate alerting on ordinary anonymous traffic (no token, malformed Authorization header, expired JWT, unknown API key). Demote that branch to Debug in middleware/connect and middleware/grpc. Genuine auth-service failures (Internal, Unavailable, Unknown) still log at Error. Returned errors are unchanged, so consumers mapping the returned error to their own status code are unaffected. --- CHANGELOG.md | 4 ++++ middleware/connect/middleware.go | 5 ++++- middleware/grpc/middleware.go | 5 ++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57e010e..195932c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Added `x-sf-meta` header to pass arbitrary metadata as trusted headers. +### Changed + +* Demote the `non-gRPC error` auth-middleware log from `Error` to `Debug` in both `middleware/connect` and `middleware/grpc` — a client failing to authenticate is not a server error, and at `Error` it flooded logs and error-rate alerts. Genuine auth-service failures (`Internal`, `Unavailable`, `Unknown`) still log at `Error`. + ## 2020-03-21 ### Changed diff --git a/middleware/connect/middleware.go b/middleware/connect/middleware.go index 9d93091..ec6ea33 100644 --- a/middleware/connect/middleware.go +++ b/middleware/connect/middleware.go @@ -78,7 +78,10 @@ func obfuscateErrorMessage(ctx context.Context, err error, logger *zap.Logger) e } return connect.NewError(connect.Code(st.Code()), errors.New(msg)) } else { - logger.Check(level, "authentication service via Connect-Web middleware non-gRPC error").Write(zap.Error(err)) + // A non-gRPC error here means the authenticator rejected the request itself (missing/malformed + // credentials, expired token, unknown API key). That's a client-side condition, not a server + // fault, so it must not pollute error logs nor error-rate alerting. + logger.Debug("authentication service via Connect-Web middleware non-gRPC error", zap.Error(err)) if v := (*dauth.ErrInvalidAuthentication)(nil); errors.As(err, &v) { return connect.NewError(connect.Code(codes.Unauthenticated), errors.New(v.Error())) diff --git a/middleware/grpc/middleware.go b/middleware/grpc/middleware.go index ed35b33..c0c38ad 100644 --- a/middleware/grpc/middleware.go +++ b/middleware/grpc/middleware.go @@ -43,7 +43,10 @@ func obfuscateErrorMessage(err error, logger *zap.Logger) error { } return status.Error(st.Code(), msg) } else { - logger.Error("authentication service via gRPC middleware non-gRPC error", zap.Error(err)) + // A non-gRPC error here means the authenticator rejected the request itself (missing/malformed + // credentials, expired token, unknown API key). That's a client-side condition, not a server + // fault, so it must not pollute error logs nor error-rate alerting. + logger.Debug("authentication service via gRPC middleware non-gRPC error", zap.Error(err)) } return status.Errorf(codes.Unauthenticated, "authentication: %s", err.Error())