semaphoreui/semaphore · error
SEMAPHORE_RUNNER_TOKEN and SEMAPHORE_RUNNER_TOKEN_FILE are…
Error message
SEMAPHORE_RUNNER_TOKEN and SEMAPHORE_RUNNER_TOKEN_FILE are mutually exclusive
What it means
Panics from ConfigInit in util/config.go when both the runner token (SEMAPHORE_RUNNER_TOKEN) and the runner token file (SEMAPHORE_RUNNER_TOKEN_FILE) are set at the same time. It is a startup validation guard: the two are alternative ways to supply the same secret, and allowing both would make it ambiguous which token is authoritative, so the process refuses to start until exactly one is configured.
Solutions
- Keep only one of the two settings: remove SEMAPHORE_RUNNER_TOKEN or unset runner_token_file / SEMAPHORE_RUNNER_TOKEN_FILE
- If you intended to switch from an inline token to a file, clear the old token value before setting the token file path
- Audit deployment manifests and .env files for both variables being injected simultaneously
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at util/config.go:940 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/7fb19dcdc145569c.
Report an issue: GitHub.
Appendix: source
Thrown at util/config.go:940
Cookie = securecookie.New(hash, encryption)
if Config.WebHost != "" {
var err error
WebHostURL, err = url.Parse(Config.WebHost)
if err != nil {
panic(err)
}
if len(WebHostURL.String()) == 0 {
WebHostURL = nil
}
} else {
WebHostURL = nil
}
if Config.Runner.Token != "" && Config.Runner.TokenFile != "" {
panic("SEMAPHORE_RUNNER_TOKEN and SEMAPHORE_RUNNER_TOKEN_FILE are mutually exclusive")
}
if Config.Runner.TokenFile != "" {
runnerTokenBytes, err := os.ReadFile(Config.Runner.TokenFile)
if err == nil {
Config.Runner.Token = strings.TrimSpace(string(runnerTokenBytes))
}
}
if Config.Subscription.KeyFile != "" {
subscriptionKeyBytes, err := os.ReadFile(Config.Subscription.KeyFile)
if err != nil {
panic(err)
}
Config.Subscription.Key = strings.TrimSpace(string(subscriptionKeyBytes))
}
View on GitHub (pinned to 1774ccb71a)