Agent Wallet Signature Expiry: Why Automated Tasks Stop Midway

 / 
2

If your agent stops running unexpectedly, the problem is usually not a crash. It is often an expired session key. I saw a quant strategy run for 89 days, just one day before the default expiry, and then the whole trading process froze. By the time someone noticed, it had already missed two important market moves. Do not rush to change your code. Use these steps to fix the problem.

The Truth: Keys Have an Expiry Date

An AI agent can make payments automatically, but it does not use your human private key. It uses a temporary 'session key.' When you authorize the agent, you give this key a time limit. When the time is up, the smart account refuses its signatures, so anything the agent sends becomes invalid.

This is a security design, not a bug. Without this expiry mechanism, if an agent gets hacked, an attacker could keep paying from your wallet until you revoke the permission. Expiry automatically cuts off risk. The problem is that many people do not notice this time limit when they set up an agent. Or they set it to the maximum, such as 180 days, and are completely unprepared when it ends, so the agent stops midway.

Step 1: Check Which Type of Expiry Stopped You

Case A: Session Expired

  • Typical signs: The agent log shows errors like Session expired, invalid session, or validUntil-related messages.

  • Cause: Agent wallets, especially ERC-4337 smart account solutions, set a TTL (Time-to-Live) when creating a session. After it expires, the smart account rejects signatures from that session key.

  • Hyperliquid example: The agent expires after 90 days by default. You can set a maximum of 180 days by adding a valid_until timestamp in agentName.

Case B: Refresh Token Expired

  • Typical signs: When using a service like Dynamic, the agent reports that refreshExp has reached its limit, or refreshAuthToken() returns 401.

  • Cause: The user JWT's refresh count or time has reached the server-side hard limit. The user has to go through the signing and authorization flow again to restore access.

Step 2: Check How Much Time Is Left on Your Current Session

What to do: Find the remaining validity of the session and confirm whether it is about to expire.

How to do it:

  • Check the configuration file or code used when creating the agent. Look for parameters related to validUntil or ttl.

  • If you use Hyperliquid, look at the timestamp added to agentName.

  • If you use an ERC-4337 wallet, check the validUntil field of the session key to see the exact expiry time.

  • If you use Dynamic, check the refreshExp field in your stored JWT. This is a hard limit that cannot be extended.

Done when: You have a clear time point, such as '2026-11-15 03:00 UTC', and you can compare it with the current time to know how much time is left.

Step 3: Renew Correctly, Do Not Wait

Case A: Session Has Expired

If the expiry is configurable, such as Hyperliquid's valid_until, you need to revoke the old session and issue a new key. The process is the same as when you first created the agent:

  1. Generate a new session keypair.

  2. Include a new valid_until timestamp in the authorization request.

  3. Sign and approve with your main account.

Note: Some toolkits, such as @cinaconnect/session-keys, support a rotate operation. This lets you rotate session keys without stopping the service. If rotation is available, do not revoke and rebuild. It avoids an extra downtime window.

Case B: Refresh Token Has Expired

Dynamic's rule is: after refreshExp is reached, it cannot be extended. You must go through the user login and authorization flow again. If your agent runs in autonomous mode, the sign-in flow can restart automatically, but only if you have stored the agent signing token safely. If you lose it, you permanently lose access to that user's wallet.

How to do it:

  • For human users, they need to log in again and sign the authorization.

  • For autonomous mode, the SDK should detect the 401 error and re-run sign-in automatically, as long as the agent signing token is safe and usable.

Important warning: Dynamic clearly warns that refreshExp is a server-side hard limit, not a soft limit. After a refresh fails with 401, any refreshAuthToken() call will fail. The only fix is to log in again. When you design agent logic, you must catch this error and trigger a re-authorization flow. Otherwise, the agent will be stuck in a 401 loop and you may not notice unless you check the logs.

Step 4: Avoid This Problem Next Time

  • Add expiry warnings in your config: Send a notification, such as email or Telegram bot, when there are 7 days, 3 days, and 1 day left before validUntil. Do not wait until it has already expired.

  • If allowed, set the expiry to the maximum: Hyperliquid allows up to 180 days. Set it to the maximum when you create the agent to reduce renewal frequency.

  • Separate payment permissions from the session lifecycle: The session can expire, but the wallet balance and limit policy remain independent. Design the agent so it can automatically trigger a rebuild after detecting session expiry, instead of getting stuck and waiting for manual help.

Final Check

Run a manual test:

  1. Set the session's validUntil to 5 minutes from now.

  2. Let the agent run normally.

  3. Wait 5 minutes and check the logs. You should see a clear expiry error, such as invalid session or expired. Check whether the agent automatically triggered the re-authorization flow or got stuck.

Checklist:

  • The logs show an expiry error code, such as Dynamic's 401 or an ERC-4337 wallet's SessionKeyExpired error.

  • The agent's audit records show a re-authorization action.

  • After re-authorization, the agent can continue subsequent tasks with no loss of funds.

If the agent does not handle expiry automatically, add an exception catch branch in the code. When an expired error appears, trigger rotateSessionKey() or a re-login flow instead of failing silently.