Steven Schlansker created KAFKA-21076:
-----------------------------------------

             Summary: Oversize decompressed telemetry payload returns 
INVALID_RECORD and permanently disables client telemetry
                 Key: KAFKA-21076
                 URL: https://issues.apache.org/jira/browse/KAFKA-21076
             Project: Kafka
          Issue Type: Bug
          Components: clients, core
    Affects Versions: 4.3.1
            Reporter: Steven Schlansker


Since [PR #22327|https://github.com/apache/kafka/pull/22327] (4.3.1, "MINOR: 
Fixed metrics decompression"), \{{ClientTelemetryUtils.decompress}} throws 
\{{TelemetryTooLargeException}} when the decompressed payload exceeds 
\{{telemetry.max.bytes}}. The call runs inside 
\{{ClientMetricsManager.processPushTelemetryRequest}} in the plugin export 
block, whose \{{catch (Throwable)}} maps every failure to 
\{{Errors.INVALID_RECORD}}:

{code:java}
catch (Throwable exception) {
    clientMetricsStats.recordPluginErrorCount(clientInstanceId);
    clientInstance.lastKnownError(Errors.INVALID_RECORD);
    log.error("Error exporting client metrics to the plugin for client instance 
id: {}", clientInstanceId, exception);
    return request.errorResponse(0, Errors.INVALID_RECORD);
}
{code}

KIP-714 defines INVALID_RECORD as "Broker failed to decode or validate the 
client's encoded metrics. Log an error and stop pushing metrics. This is viewed 
as a problem in the client implementation of metrics serialization that is not 
likely to be resolved by retrying." The Java client implements exactly that in 
\{{ClientTelemetryUtils.maybeFetchErrorIntervalMs}}: on INVALID_RECORD it sets 
the push interval to \{{Integer.MAX_VALUE}}, so telemetry from that client 
instance stops until the process restarts.

KIP-714 defines TELEMETRY_TOO_LARGE for a payload that is too large, and the 
client handles that code by retrying at the normal interval.

Observed effect: after a broker upgrade from 4.3.0 to 4.3.1, every Kafka 
Streams stream-thread consumer (payload several MB decompressed, under 1 MiB 
compressed) got INVALID_RECORD on its next push and disabled its telemetry. All 
\{{org.apache.kafka.stream.\*}} metrics that KIP-1076 routes through the 
stream-thread consumers disappeared from the metrics backend in every 
environment at the same time. Broker log:

{noformat}
ERROR Error exporting client metrics to the plugin for client instance id: 
xkdFrlXGTGig-RPx5SjuQA (org.apache.kafka.server.ClientMetricsManager)
org.apache.kafka.common.errors.TelemetryTooLargeException: Decompressed 
telemetry metrics exceed maximum allowed size: 1048576
{noformat}

Two further points:

* KIP-714 documents \{{telemetry.max.bytes}} as "The maximum size (after 
compression if compression is used) of telemetry pushed from a client to the 
broker." PR #22327 changed the meaning to also bound the decompressed size, 
with no KIP update, no release note, and no new configuration. A 4.3.0 cluster 
that accepted a client's pushes rejects the same pushes on 4.3.1.
* Before PR #22327 the same code path allocated \{{metrics.limit() \* 2}} bytes 
and grew without bound, so a bound is reasonable. The bound needs its own error 
code and, given that decompression ratios of 10x or more are normal for OTLP 
metrics, its own configuration or a multiple of \{{telemetry.max.bytes}}.

Suggested fix: catch \{{TelemetryTooLargeException}} before the generic 
\{{catch (Throwable)}} and return \{{Errors.TELEMETRY_TOO_LARGE}}, so the 
client retries at its interval instead of disabling telemetry. Document the 
decompressed bound in \{{telemetry.max.bytes}} or add a separate configuration, 
and mention the behavior change in the upgrade notes.

Workaround: raise \{{telemetry.max.bytes}} on the brokers and restart affected 
clients.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to