henrygd/beszel · error
invalid signature - check KEY value
Error message
invalid signature - check KEY value
What it means
During the auth challenge, the hub sends a challenge that the client signs with its private key; verifySignature verifies the returned signature (or signs and verifies the token) against the KEY-derived public key. If no signature scheme succeeds (pubKey.Verify fails for the token), the library concludes the key/token combination is wrong and throws this error. It does not necessarily mean the wire data is corrupt — most often the configured KEY does not correspond to the token or the hub's expectation.
Source
Thrown at agent/client.go:250
serverAddr := client.agent.connectionManager.serverOptions.Addr
_, response.Port, _ = net.SplitHostPort(serverAddr)
}
return client.sendResponse(response, requestID)
}
// verifySignature verifies the signature of the token using the public keys.
func (client *WebSocketClient) verifySignature(signature []byte) (err error) {
for _, pubKey := range client.agent.keys {
sig := ssh.Signature{
Format: pubKey.Type(),
Blob: signature,
}
if err = pubKey.Verify([]byte(client.token), &sig); err == nil {
return nil
}
}
return errors.New("invalid signature - check KEY value")
}
// Close closes the WebSocket connection gracefully.
// This method is safe to call multiple times.
func (client *WebSocketClient) Close() {
if client.Conn != nil {
_ = client.Conn.WriteClose(1000, nil)
}
}
// handleHubRequest routes the request to the appropriate handler using the handler registry.
func (client *WebSocketClient) handleHubRequest(msg *common.HubRequest[cbor.RawMessage], requestID *uint32) error {
ctx := &HandlerContext{
Client: client,
Agent: client.agent,
Request: msg,
RequestID: requestID,
HubVerified: client.hubVerified,View on GitHub (pinned to b38fb7dafa)
Solutions
- Regenerate/confirm that KEY and TOKEN were issued together from the hub and paste the full untruncated values.
- Compare the agent's KEY with the public key registered on the hub for this agent ID.
- Verify the token is well-formed and not expired; re-fetch a fresh token from the hub.
- Confirm both sides use the same signature algorithm and encoding; update agent or hub versions if they diverge.
Example fix
// before HUB_URL=wss://hub.prod KEY="Kf2..." # key from staging TOKEN="eyJ..." # issued by prod hub // after HUB_URL=wss://hub.prod KEY="<prod key matching this TOKEN>" TOKEN="eyJ..."
Defensive patterns
Strategy: try-catch
Validate before calling
// before connecting, sanity-check the key material
key, err := base64.StdEncoding.DecodeString(strings.TrimSpace(keyEnv))
if err != nil {
return fmt.Errorf("KEY is not valid base64: %w", err)
}
if len(key) != expectedKeyLen {
return fmt.Errorf("KEY length %d, expected %d — likely truncated", len(key), expectedKeyLen)
} Try / catch
err = verifySignature(client, challenge)
if err != nil {
if strings.Contains(err.Error(), "invalid signature") {
log.Error("auth failed: KEY does not match TOKEN/hub expectation; refetch credentials")
// do NOT blind-retry with the same key; rotate credentials first
return errAuthRetryableAfterRefresh
}
return err
} Prevention
- Issue KEY and TOKEN together from the hub and store/rotate them as a pair.
- Paste keys in full; verify length and that no whitespace/newlines were introduced.
- Pin and test against the same hub environment the credentials were issued for.
- Keep agent and hub signature-algorithm versions in sync.
- Log only the failure, never the key or token contents.
When it happens
Trigger: handleAuthChallenge receives a challenge; the client signs the token with its private key but verification against pubKey fails — KEY is wrong, mismatched with TOKEN, the token is malformed/expired for signing purposes, or the signature algorithm/encoding differs from what the hub expects.
Common situations: Rotating TOKEN without updating KEY (or vice versa) on the hub; copy-paste truncating the base64 KEY; hub and agent using different key algorithms (ed25519 vs ecdsa); agent pointed at the wrong hub environment (staging key vs prod hub).
Related errors
- HUB_URL environment variable not set
- must set TOKEN or TOKEN_FILE
- hub not verified
- no matching fingerprints
- fingerprint mismatch
AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31).
Data as JSON: /api/errors/87ee0bdb42ae87b2.
Report an issue: GitHub.