microsoft/aspire · critical
failed to authenticate to AppHost
Error message
failed to authenticate to AppHost: %w
What it means
After the socket connection succeeds, connect authenticates using the ASPIRE_REMOTE_APPHOST_TOKEN environment variable. If c.authenticate fails (wrong, missing, or expired token, or protocol mismatch during handshake), the connection is torn down and the cause is wrapped as "failed to authenticate to AppHost: %w".
Solutions
- Run the project through `aspire run` so ASPIRE_REMOTE_APPHOST_TOKEN is injected fresh and matches the current AppHost.
- Never hardcode or copy the token between sessions; it is per-run.
- Log the unwrapped error to distinguish bad token vs handshake/timeout failure.
- Restart both AppHost and project together so token and socket stay in sync.
Example fix
// before
authToken := os.Getenv("ASPIRE_REMOTE_APPHOST_TOKEN")
// after
authToken := os.Getenv("ASPIRE_REMOTE_APPHOST_TOKEN")
if authToken == "" {
return fmt.Errorf("ASPIRE_REMOTE_APPHOST_TOKEN is not set; launch via `aspire run` instead of running directly")
} Defensive patterns
Strategy: try-catch
Validate before calling
if os.Getenv("ASPIRE_REMOTE_APPHOST_TOKEN") == "" {
log.Fatal("ASPIRE_REMOTE_APPHOST_TOKEN missing; launch via `aspire run`")
} Try / catch
app, err := aspire.CreateBuilder(ctx)
if err != nil && strings.Contains(err.Error(), "failed to authenticate") {
log.Fatal("stale or missing ASPIRE_REMOTE_APPHOST_TOKEN; restart via `aspire run`")
} Prevention
- Treat the token as per-run; never copy or hardcode it.
- Restart client and AppHost together so token and socket stay paired.
- Launch only through `aspire run` so env injection happens automatically.
- Add a pre-flight check for the token env var before connecting.
When it happens
Trigger: ASPIRE_REMOTE_APPHOST_TOKEN is empty or doesn't match the token the AppHost expects; connecting to an AppHost from a different session/run whose token differs; authenticate handshake times out or the AppHost rejects the auth frame.
Common situations: Manually running the Go project with a stale token from a previous `aspire run` session; copying env vars between machines; AppHost regenerated its token after restart while the client kept the old value.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- failed to authenticate to the AppHost server
- ASPIRE_REMOTE_APPHOST_TOKEN environment variable is not set
- failed to connect to AppHost
- -32000
- aspire: dict getter returned unexpected type %T
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/e7c1661fe4d9527d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.CodeGeneration.Go/Resources/transport.go:644
return fmt.Errorf("failed to connect to AppHost: %w", err)
}
authToken := os.Getenv("ASPIRE_REMOTE_APPHOST_TOKEN")
if authToken == "" {
cErr := rawConn.Close()
c.mu.Unlock()
return errors.Join(errors.New("ASPIRE_REMOTE_APPHOST_TOKEN environment variable is not set"), cErr)
}
conn := newConnection(rawConn, c, c.onConnectionClose)
c.conn = conn
c.mu.Unlock()
conn.start()
if err := c.authenticate(ctx, authToken); err != nil {
c.disconnect()
return fmt.Errorf("failed to authenticate to AppHost: %w", err)
}
return nil
}
// onDisconnect registers a callback to be invoked exactly once when the
// connection is closed.
func (c *client) onDisconnect(callback func()) {
c.mu.Lock()
c.disconnectCallbacks = append(c.disconnectCallbacks, callback)
c.mu.Unlock()
}
// invokeCapability invokes a capability on the server. The supplied context
// drives both server-side cancellation (if a CancellationToken is registered
// in args) and local short-circuit on cancel.
func (c *client) invokeCapability(ctx context.Context, capabilityID string, args map[string]any) (any, error) {
if err := validateCapabilityArgs(capabilityID, args); err != nil {View on GitHub (pinned to 25830f84bd)