pinpoint-apm/pinpoint · warning

Cannot stop agent. Current status =

Error message

Cannot stop agent. Current status = [{}]

What it means

WARN log from DefaultAgent.close() when the agent is not in the RUNNING state, so it cannot transition to STOPPED and close() returns without releasing resources. The parameter {} is the current AgentStatus (e.g. INITIALIZING, STOPPED). applicationContext.close() is skipped, which can leave background threads alive if callers assume shutdown happened.

Solutions

  1. Call close() only when getStatus() == AgentStatus.RUNNING; check status first.
  2. Make shutdown idempotent on your side with a boolean/closed flag so close() runs once.
  3. If the agent never started, do not call close(); dispose of the instance differently or fix the startup failure first.
  4. Ensure only one shutdown hook owns the agent lifecycle.

Example fix

// before
runtime.addShutdownHook(new Thread(() -> agent.close()));
agent.close(); // warn: Cannot stop agent. Current status = [STOPPED]

// after
private final AtomicBoolean closed = new AtomicBoolean(false);
void shutdown() {
    if (closed.compareAndSet(false, true) && agent.getStatus() == AgentStatus.RUNNING) {
        agent.close();
    }
}
Defensive patterns

Strategy: type-guard

Validate before calling

boolean canStop = (agent.getStatus() == AgentStatus.RUNNING);
if (canStop) agent.close();

Type guard

boolean isClosable(DefaultAgent a) { return a.getStatus() == AgentStatus.RUNNING; }

Try / catch

try {
    if (agent.getStatus() == AgentStatus.RUNNING) agent.close();
} catch (Exception e) {
    log.warn("agent shutdown failed", e); // don't rethrow from shutdown hooks
}

Prevention

When it happens

Trigger: Calling close() before start() (status INITIALIZING), calling close() twice (second call sees STOPPED), or closing during a failed startup that never reached RUNNING.

Common situations: Shutdown hooks racing each other and both calling close(); cleanup code in tests tearing down an agent that failed to start; double-close in application stop sequences.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/DefaultAgent.java:267

                public void run() {
                    logger.info("stop() started. threadName:" + Thread.currentThread().getName());
                    DefaultAgent.this.close();
                }
            });

            shutdownHookRegister.register(shutdownThread);

        }

    }

    @Override
    public void close() {
        synchronized (agentStatusLock) {
            if (this.agentStatus == AgentStatus.RUNNING) {
                changeStatus(AgentStatus.STOPPED);
            } else {
                logger.warn("Cannot stop agent. Current status = [{}]", this.agentStatus);
                return;
            }
        }
        logger.info("Stopping pinpoint Agent.");
        this.applicationContext.close();

        // for testcase
        if (agentOption.isStaticResourceCleanup()) {
            this.loggingSystem.close();
        }
    }

}

View on GitHub (pinned to 744c3d3075)