pinpoint-apm/pinpoint · warning

agentDataSender close fail

Error message

agentDataSender close fail

What it means

In GrpcModuleLifeCycle.shutdown(), agentDataSender (used for agent information/handshake data) is closed with IOUtils.closeQuietly; any close exception is logged as "agentDataSender close fail". Like the sibling warnings, it is logged and shutdown proceeds.

Source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/GrpcModuleLifeCycle.java:111

        logger.info("spanDataSenderProvider:{}", spanDataSender);

        this.statDataSender = this.statDataSenderProvider.get();
        logger.info("statDataSenderProvider:{}", statDataSender);

        this.dnsExecutorService = dnsExecutorServiceProvider.get();
        logger.info("dnsExecutorServiceProvider:{}", dnsExecutorService);

        this.reconnectScheduledExecutorService = reconnectScheduledExecutorProvider.get();
        logger.info("reconnectScheduledExecutorServiceProvider:{}", reconnectScheduledExecutorService);

    }

    @Override
    public void shutdown() {
        logger.info("shutdown()");
        IOUtils.closeQuietly(spanDataSender, (ex) -> logger.warn("spanDataSender close fail", ex));
        IOUtils.closeQuietly(statDataSender, (ex) -> logger.warn("statDataSender close fail", ex));
        IOUtils.closeQuietly(agentDataSender, (ex) -> logger.warn("agentDataSender close fail", ex));
        IOUtils.closeQuietly(metadataDataSender, (ex) -> logger.warn("metadataDataSender close fail", ex));

        if (dnsExecutorService != null) {
            if (!MoreExecutors.shutdownAndAwaitTermination(dnsExecutorService, Duration.ofSeconds(3))) {
                logger.warn("dnsExecutor shutdown failed");
            }
        }
        if (reconnectScheduledExecutorService != null) {
            if (!MoreExecutors.shutdownAndAwaitTermination(reconnectScheduledExecutorService, Duration.ofSeconds(3))) {
                logger.warn("reconnectScheduledExecutor shutdown failed");
            }
        }
        IOUtils.closeQuietly(reporter, (ex) -> logger.warn("reporter close fail", ex));
    }

    @Override
    public String toString() {
        return "GrpcModuleLifeCycle{" +

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Review the logged cause; stale-connection errors at exit are typically harmless
  2. Ensure the collector is reachable during graceful shutdowns, or accept the warning on forced terminations
  3. Keep only one lifecycle shutdown path; concurrent shutdowns of the same sender cause close failures
  4. Consider short keepalive/idle-timeout tuning so dead channels are detected before shutdown
Defensive patterns

Strategy: try-catch

Validate before calling

if (channel != null && channel.isShutdown()) { logger.warn("agent channel already closed; skip graceful close"); }

Type guard

boolean isClosable(Object sender) { return sender instanceof io.grpc.ManagedChannel && !((io.grpc.ManagedChannel) sender).isShutdown(); }

Try / catch

try {
  profiler.stop();
} catch (Throwable t) {
  logger.warn("Profiler shutdown incomplete; agentDataSender failure logged separately", t);
}

Prevention

When it happens

Trigger: Closing agentDataSender at shutdown while its gRPC channel or stream is already failed/closed — e.g. lost connection to collector, channel shutdown already in progress, or pending RPC failing during close().

Common situations: Collector restarted before agent shutdown, long-running agents with stale TCP connections killed by firewalls/LBs, JVM shutdown hooks firing after network teardown (e.g. container stop).

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/6335a9c41dd27c8d. Report an issue: GitHub.