aaif-goose/goose · critical
GOOSE_SERVER__SECRET_KEY must be set when using GOOSE_EXTERN
Error message
GOOSE_SERVER__SECRET_KEY must be set when using GOOSE_EXTERNAL_BACKEND. Set it to the same value on both the server and the desktop client.
What it means
At startup, main.ts reads GOOSE_EXTERNAL_BACKEND to point the desktop at an externally-run goose server instead of spawning one. That protocol requires a shared auth secret, so if GOOSE_EXTERNAL_BACKEND is set but GOOSE_SERVER__SECRET_KEY is empty, getExternalBackendFromEnv throws this immediately — it refuses an unauthenticated connection to a remote backend.
Source
Thrown at ui/desktop/src/main.ts:929
}
const configuredUrl = process.env.GOOSE_EXTERNAL_BACKEND_URL?.trim();
if (configuredUrl) {
return configuredUrl;
}
return `http://127.0.0.1:${process.env.GOOSE_PORT || '3000'}`;
};
const getExternalBackendFromEnv = (): ExternalBackend | null => {
const url = getExternalBackendUrlFromEnv();
if (!url) {
return null;
}
const secret = process.env.GOOSE_SERVER__SECRET_KEY;
if (!secret) {
throw new Error(
'GOOSE_SERVER__SECRET_KEY must be set when using GOOSE_EXTERNAL_BACKEND. ' +
'Set it to the same value on both the server and the desktop client.'
);
}
return {
source: 'env',
url,
secret,
};
};
const getServerSecret = (settings: Settings): string => {
if (settings.externalGoosed?.enabled && settings.externalGoosed.secret) {
return settings.externalGoosed.secret;
}
return GENERATED_SECRET;
};View on GitHub (pinned to 3810898a74)
Solutions
- Export GOOSE_SERVER__SECRET_KEY in the desktop client's environment with the exact same value the server was started with
- Double-check spelling and dunder: GOOSE_SERVER__SECRET_KEY (two underscores between SERVER and SECRET_KEY)
- If you did not intend an external backend, unset GOOSE_EXTERNAL_BACKEND so the app spawns its local backend and generates its own secret
Example fix
# before export GOOSE_EXTERNAL_BACKEND=http://10.0.0.5:8000 open Goose.app # throws # after (same value the server used) export GOOSE_SERVER__SECRET_KEY="$SECRET" export GOOSE_EXTERNAL_BACKEND=http://10.0.0.5:8000 open Goose.app
Defensive patterns
Strategy: validation
Validate before calling
// Run before app.whenReady():
const url = process.env.GOOSE_EXTERNAL_BACKEND;
if (url && !process.env.GOOSE_SERVER__SECRET_KEY) {
throw new Error('GOOSE_EXTERNAL_BACKEND requires GOOSE_SERVER__SECRET_KEY');
} Type guard
const hasExternalBackendConfig = (): boolean => Boolean(process.env.GOOSE_EXTERNAL_BACKEND) && Boolean(process.env.GOOSE_SERVER__SECRET_KEY && process.env.GOOSE_SERVER__SECRET_KEY.length > 0);
Try / catch
try {
backend = getExternalBackendFromEnv();
} catch (e) {
// config error: print the message and exit; do not fall back to local backend silently
dialog.showErrorBox('Configuration error', e instanceof Error ? e.message : String(e));
app.quit();
} Prevention
- Document the env pair together; validate both at startup in one place
- Use a dotenv file loaded explicitly by the launcher rather than inherited shell env
- Add a smoke-test script that asserts env pairing before deploying clients
When it happens
Trigger: Launching Goose Desktop with GOOSE_EXTERNAL_BACKEND=http://host:port but no GOOSE_SERVER__SECRET_KEY in the environment; secret set in the server's shell but not in the one launching Electron; typo in the variable name (e.g. GOOSE_SERVER_SECRET_KEY) so it reads undefined.
Common situations: Teams running goose serve centrally and connecting desktop clients; CI launching the app against a test backend; secret managed via dotenv file that isn't loaded because the app was started from Finder/Dock rather than a shell.
Related errors
- GOOSE_SERVER__SECRET_KEY is required for goose serve
- missing required key {}: {}
- Missing env vars for provider '{provider}': {', '.join(missi
- OPENAI_API_KEY environment variable is not set, but is neede
- Failed to store secret
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/391549a8a0e2d622.
Report an issue: GitHub.