[BUG] Stale Claude Code client/session kept consuming usage; difficult to identify responsible authorization token

Status Open
Reported on v2.1.224
Maintainer reply None cached
Activity 0 comments · opened Sep 24, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Stale Claude Code client/session kept consuming usage; difficult to identify responsible authorization token

Summary

I ran into a case where Claude Code usage continued to consume essentially my entire rolling/session allowance even though I was no longer actively using Claude.

The incident started while I was working on a BorgBackup task using an agent setup I orchestrate myself.

During that work I hit my weekly usage limit. I stopped working and waited until usage became available again.

After the weekly limit recovered, however, I still could not meaningfully use Claude: the shorter rolling/session limit would repeatedly reach 100% despite me not actively using Claude. This happened across multiple reset windows.

I initially suspected a persistent Claude process on one of my servers. I shut that machine down completely and investigated the issue separately.

The eventual evidence points instead to an old Claude Code client/session, probably on another machine, repeatedly resuming or retrying an earlier session while still holding a valid Claude Code authorization token.

Revoking old Claude Code authorization tokens appears to have stopped the behavior.

I had accumulated more than 70 Claude Code authorization tokens, with the oldest dating back to March.

I think this exposed an important failure mode: an abandoned/stuck Claude Code process can apparently continue consuming account usage for a long time if its authorization remains valid, while it is difficult for the user to determine which token/client is responsible.

---

Environment

Observed on/around:

  • Claude Code 2.1.224
  • Linux/Debian hosts
  • Claude Code CLI
  • Remote/background Claude Code sessions
  • Long-running agent workflows
  • Multiple machines using the same Claude account
  • OAuth-based Claude Code authentication

Some older sessions used models including claude-opus-4-8.

I also use systemd timers and custom agent orchestration, so I initially assumed one of my own services was responsible.

---

What happened

1. Original task

I was working on a BorgBackup task with ChatGPT.

Separately, I had several Claude Code environments and long-lived agent/session setups on my machines.

My suspicion is that when Claude Code later started or resumed, it loaded a large amount of existing project/session context from disk and/or resumed an older prompt/session state. The BorgBackup work itself was not initiated in Claude Code.

2. Usage recovered, but the shorter limit immediately became unusable

Once weekly usage became available again, I expected normal operation.

Instead, my shorter rolling/session usage repeatedly reached:

100% used

even though I had not been using Claude.

At one point I had been asleep during much of the period in question.

The weekly usage also continued climbing substantially. Examples from the same day:

  • ~05:54 — weekly usage ~42%, current session 100%
  • ~10:15 — weekly usage ~55%, current session 100%
  • ~14:34 — weekly usage ~70%, current session 100%

Roughly 28 percentage points of weekly usage disappeared over less than nine hours. This continued across more than one rolling-limit reset.

3. Initial suspect: persistent Claude process on a server

I have a VM used for agent orchestration. It had an old persistent Claude daemon/session, including a background notification watcher. The process tree included a long-lived Claude daemon and an old forked/resumed Claude session. There was also a shell watcher polling Forgejo notifications once per minute.

Initially this looked suspicious because the Claude process had been alive for weeks. However, inspection showed that the watcher itself did not invoke Claude — it only polled notifications and printed messages when appropriate.

I then inspected the corresponding Claude JSONL logs. An important discovery was that the original session and its fork had different session IDs. The old source session had not received real model responses since August. The forked session had not received real model responses since September 10. No new assistant inference events corresponding to the mysterious usage were present.

4. Global search of Claude Code session logs

I searched every Claude Code JSONL session on the server for actual assistant responses with non-synthetic token usage during the affected period. Conceptually:

find ~/.claude/projects -type f -name '*.jsonl' -print0 |
while IFS= read -r -d '' f; do
  jq -r --arg f "$f" '
    select(
      .type == "assistant"
      and .message.usage != null
      and .message.model != "<synthetic>"
      and .timestamp >= "<affected-window>"
    )
    | [
        .timestamp,
        .message.model,
        (.message.usage.input_tokens // 0),
        (.message.usage.cache_read_input_tokens // 0),
        (.message.usage.cache_creation_input_tokens // 0),
        (.message.usage.output_tokens // 0),
        $f
      ] | @tsv
  ' "$f"
done | sort

Result: no real inference events during the affected window. There were some recently modified JSONL files, but their new records were synthetic/local bookkeeping events rather than model calls. This ruled out the obvious long-running Claude session as the direct source of the usage.

5. I shut the orchestration VM down completely

To isolate the problem, I powered the entire VM off at the hypervisor level. This eliminated:

  • Claude daemons
  • background PTYs
  • notification watchers
  • systemd user services
  • timers
  • local Claude Code processes

Usage still behaved abnormally before credential cleanup. This suggested the source was not simply a currently running process on that VM.

6. I inspected Claude Code sessions and authorization tokens

In the Claude UI I found many old Claude Code sessions, some of which still appeared as "Connected." More importantly, I discovered that my account had accumulated 70+ Claude Code authorization tokens. The oldest token was from approximately March. This was far more authorization state than I expected to exist.

Given that I use several machines and had previously experimented with persistent/background Claude Code sessions, this created a very large credential/session surface. At this point I considered the possibility that an older machine/client still had a valid token and was retrying or resuming an earlier Claude Code task.

7. Credential cleanup

I revoked the old Claude Code authorization tokens and cleaned up old sessions.

After that cleanup, and with the orchestration VM still powered off, the next usage window showed:

Current session: 0% used Starts when a message is sent

and stayed there. This was the first clean reset I had observed during the incident.

8. Bringing the VM back online

I then powered the orchestration VM back on to determine whether simply booting it would reproduce the issue. No Claude processes were running after boot.

One systemd service looked initially suspicious: claude-orch.service. It was configured as a persistent Claude Code remote-control service with Restart=always. However, journal inspection showed that it failed at the CHDIR stage because its configured working directory no longer existed:

status=200/CHDIR
Changing to the requested working directory failed: No such file or directory

Therefore Claude itself was never executed by this service. I disabled the service anyway.

9. Other autonomous services checked

The host also contained automation capable of running Claude headlessly.

  • An old loop-engine.service was designed to classify queued tasks and run low-risk ones through claude -p. However, its timer was not active, and no relevant Claude runs occurred during the incident.
  • Another active service, brood-loop, ran every 15 minutes, but the journal consistently showed no due task (...) — nothing to do this pulse, so it never dispatched Claude.
  • gh-consumer only attempted to consume an external queue and was failing with HTTP 401. It did not invoke Claude.
  • md-monitor was an observe-only filesystem scanner. It did not invoke Claude.

At this point the VM could remain online without causing the Claude usage counter to increase.

---

Current hypothesis

The best explanation consistent with the evidence is:

  1. The BorgBackup work itself was performed with ChatGPT, not Claude Code.
  2. An older Claude Code client/process later started, resumed, or reconnected using an existing authorization token.
  3. That Claude Code environment may have loaded substantial existing project/session context from disk at startup or resumed an older prompt/session state.
  4. The client then appears to have continued making requests without my active interaction.
  5. Because many historical Claude Code authorization tokens remained valid, it was difficult to identify which client/token was responsible.
  6. Revoking the accumulated old Claude Code tokens appears to have stopped the behavior.

In simplified form:

old/stuck Claude Code client
        |
        v
valid historical OAuth token
        |
        v
resume/retry previous session or prompt
        |
        v
model requests
        |
        v
rolling usage repeatedly exhausted

I cannot prove which exact process made the requests, because the relevant client has not been identified from the server-side logs available to me. So I would not characterize this as "the token itself was looping." Rather: a stale Claude Code client appears to have been able to continue/retry work indefinitely because its old authorization remained valid.

---

Context-length observation

During the investigation I also discovered extremely large historical Claude Code contexts. For example, some old turns contained roughly:

input_tokens:               2
cache_read_input_tokens:    ~810,000+
output_tokens:              hundreds/thousands

This explained why some old sessions were extremely expensive per turn. However, context length alone does not explain the incident described here: the mysterious usage continued across fresh rolling-limit resets without matching model calls in the server's Claude Code logs. It is therefore a separate issue from simply having an oversized context.

---

Why I think this matters

There are several UX/security issues here.

1. Token accumulation. I had more than 70 Claude Code authorization tokens and did not realize that so many historical authorizations remained valid. For users experimenting with remote control, background agents, headless Claude Code, multiple hosts, containers/VMs, or disposable development environments, this can become difficult to reason about very quickly.

2. Attribution. When usage began disappearing, I had no obvious way to answer: which Claude Code client/token/session is consuming my usage right now? That would have reduced this investigation from hours to minutes.

3. Stale processes. A detached or forgotten Claude Code client with valid credentials can potentially continue operating long after the user mentally considers that session finished.

4. Usage visibility. The account usage page showed that consumption was happening, but not where it originated. There was no obvious mapping such as:

usage → token → device → Claude Code session → host → model → timestamp

---

Suggested improvements

Any of the following would have made this substantially easier to diagnose.

Per-token activity. For every Claude Code authorization token, show: created date, last-used date/time, approximate device/host, Claude Code version, active/inactive state, number of current sessions, recent usage attributable to it.

Per-session usage attribution. Expose something like:

Session             Last request       Usage
------------------------------------------------
<session A>         10:14              ...
<session B>         10:02              ...

Detect obviously stale authorizations. Warn when an account has dozens of historical Claude Code authorization tokens, e.g.: "You have 74 active Claude Code authorizations, including tokens older than six months."

Easier global revocation. Provide an obvious "Revoke all Claude Code authorizations" action.

Identify repeated resume/reconnect loops. If one client repeatedly reconnects/resumes the same session while consuming significant usage, surface that explicitly, e.g.: "Claude Code on device X has resumed this session 37 times in the last hour."

Usage audit trail. Even a short server-side history — timestamp, model, Claude Code session ID, authorization/token ID, request/token usage, client version — would be extremely useful.

---

Resolution

After:

  • shutting down the initially suspected VM
  • investigating persistent Claude sessions
  • verifying that the suspected server logs contained no corresponding inference calls
  • revoking a large number of historical Claude Code authorization tokens
  • cleaning up old sessions

the usage drain stopped.

I later brought the VM back online while keeping the problematic Claude automation disabled, and usage did not immediately resume. This strongly suggests that the problem was associated with an old authorized Claude Code client/session rather than the VM itself.

I am filing this primarily because Claude Code currently makes it difficult to identify a rogue/stale authorized client when account usage is being consumed unexpectedly.

What Should Happen?

Claude Code should make it possible to identify and stop the specific client/token consuming usage, instead of forcing a blind sweep of every server, session, and authorization token. At minimum: visible last-used/device info per authorization token, and a warning when dozens of old tokens remain valid.

Error Messages/Logs

Steps to Reproduce

  1. Use Claude Code across multiple machines/sessions over an extended period (months), including background/remote/headless sessions, without ever revoking old authorization tokens.
  2. Hit the weekly usage limit during active work; stop and wait for it to reset.
  3. After the weekly limit recovers, observe the shorter rolling/session limit repeatedly showing 100% used despite no active use.
  4. Rule out currently-running local processes as the cause (no matching inference events in local Claude Code JSONL logs for the affected window).
  5. Revoke all old/unused Claude Code authorization tokens (70+ accumulated, oldest from ~March) and observe that the rolling limit resets to 0% and stays there.

I cannot provide a minimal deterministic repro — the issue only became visible after months of accumulated authorizations across multiple clients, and I could not identify which specific client/token was the direct cause before revoking them all.

Claude Model

Sonnet (default)

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.224

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

Other

Additional Information

_No response_

View original on GitHub ↗