invalid_signature (401)
What you’ll see
{ "error": "Invalid JWT", "correlation_id": "..." }HTTP status 401. The proxy could not verify the JWT in the
Authorization: Bearer header against the agent’s registered public key.
Repeated invalid_signature failures count toward the
circuit breaker — three in a row
suspends the agent.
Why
Every /v1/actions call carries an RS256 JWT signed by the agent’s
private key. The proxy looks up the agent’s public key (PEM, stored in
agents.public_key_pem) and verifies the signature.
Four common causes:
- The agent’s private key on disk doesn’t match the registered public key. Most often happens after re-registering an agent under the same name — re-registration rotates the keypair, but the agent host is still using the old private key.
- The JWT is malformed. Wrong algorithm (HS256 instead of RS256),
missing required claims (
agent_id,owner_id,iat,exp), orexpalready past. - The agent was deleted or soft-deleted. The lookup for the public key returns nothing and the proxy treats it as an invalid signature.
- Clock skew. If the agent’s clock is more than the proxy’s leeway
window behind,
iatlooks future-dated. We allow 30 seconds of skew; anything beyond fails verification.
Fix
Most cases: re-install the agent on this machine
- In the dashboard, open Agents → your agent → Install on another machine.
- Generate a fresh install token.
- On the agent’s machine, run the install command shown in the modal. This rotates the keypair on the server and writes the new private key to your machine. The agent immediately uses the new key.
See Install on another machine.
MCPB / Claude Desktop
In the AgentValet MCPB config, re-paste the AGENT_PRIVATE_KEY_B64 value
from the dashboard’s Install on Claude Desktop modal. Claude Desktop
will reload the MCP server with the new key on next launch.
Self-built JWT signer
If you wrote your own JWT signer (custom MCP server, integration testing), verify:
- Algorithm:
RS256(notHS256) - Required claims:
agent_id,owner_id,iat,exp(exp≤ 5 min fromiatrecommended) Authorization: Bearer <jwt>exactly — noToken, no quoted value- Private key matches the public key registered for the agent
Clock skew
date +%s on the agent machine vs curl -sI https://api.agentvalet.ai/health | grep -i date from the same shell. If the offset is more than 30 seconds,
fix the agent host’s NTP configuration.
Related guides
- Register via the CLI
- Install on another machine
- Re-auth a platform (different failure mode but adjacent)