Skip to content

Broker reports a rotate-token failure as "explicit workspace key was rejected", misdirecting diagnosis #1599

Description

@khaliqgant

Summary

When agent-name reclaim fails at the rotate_agent_token step,
startup_single_session_set_from_sources relabels the error as the workspace
key
being rejected. The workspace key was accepted; a later call on a different
credential class was not. This cost six days of misdiagnosis on a production
outage, with the investigation aimed at credential provisioning while the key was
never the problem.

What the operator sees

Error: failed to initialize relaycast session
Caused by:
    0: explicit workspace key from AGENT_RELAY_WORKSPACE_KEY was rejected
    1: Agent token required (at_live_...)

Cause 0 asserts the key was rejected. Cause 1 is the real reason, and it is about
a different credential entirely. Every reading of cause 0 sends you to check the
key, its scope, and how it is provisioned - all of which are fine.

Mechanism

In crates/broker/src/relaycast/auth.rs, admit_agent_registration (:985) has a
409 branch:

let existing = relay.get_agent(name).await...?;      // 200 with the workspace key
...
let token_response = relay.rotate_agent_token(&existing.name).await...?;  // 401

That 401 propagates out of register_agent_with_workspace_key. The caller at
:551 matches Err(error) if is_auth_rejection(&error) and, because
candidate.explicit_join is set, wraps it with:

"explicit workspace key from {} was rejected"

is_auth_rejection only tests the HTTP status, so a 401 from the rotate call is
indistinguishable from a 401 on the registration call, and both get the
registration wording.

Suggested fix

Attribute the failure to the call that produced it. The registration-rejected
wording should apply only when register_agent itself was rejected; a failure
from get_agent or rotate_agent_token inside the conflict branch should say so,
naming the credential class the endpoint actually wanted. Cause 1 already carries
the right information - it is cause 0 that overrides it with a confident wrong
answer.

This is a diagnosis fix, not a repair: the underlying reason a broker cannot
rotate its own token with a workspace key is filed against relaycast.

Reproduction

With broker 11.8.1, run init --persist --state-dir <dir> twice with the same
--instance-name and the same state dir, using a valid workspace key. The first
boot succeeds; the second produces the error above. A deliberately invalid key
produces Invalid API key instead, confirming the second-boot failure is not
about key validity.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions