henrygd/beszel · critical
HUB_URL environment variable not set
Error message
HUB_URL environment variable not set
What it means
newWebSocketClient reads the hub endpoint from the HUB_URL environment variable before constructing the WebSocketClient. If HUB_URL is unset (utils.GetEnv returns exists=false), the client cannot know where to connect and throws this error immediately, before any URL parsing or connection attempt.
Source
Thrown at agent/client.go:50
type WebSocketClient struct {
gws.BuiltinEventHandler
options *gws.ClientOption // WebSocket client configuration options
agent *Agent // Reference to the parent agent
Conn *gws.Conn // Active WebSocket connection
hubURL *url.URL // Parsed hub URL for connection
token string // Authentication token for hub registration
fingerprint string // System fingerprint for identification
hubRequest *common.HubRequest[cbor.RawMessage] // Reusable request structure for message parsing
lastConnectAttempt time.Time // Timestamp of last connection attempt
hubVerified bool // Whether the hub has been cryptographically verified
}
// newWebSocketClient creates a new WebSocket client for the given agent.
// It reads configuration from environment variables and validates the hub URL.
func newWebSocketClient(agent *Agent) (client *WebSocketClient, err error) {
hubURLStr, exists := utils.GetEnv("HUB_URL")
if !exists {
return nil, errors.New("HUB_URL environment variable not set")
}
client = &WebSocketClient{}
client.hubURL, err = url.Parse(hubURLStr)
if err != nil || client.hubURL.Host == "" {
return nil, fmt.Errorf("invalid HUB_URL %q: must include scheme and host (e.g. http://hub.example.com:8090)", hubURLStr)
}
// get registration token
client.token, err = getToken()
if err != nil {
return nil, err
}
client.agent = agent
client.hubRequest = &common.HubRequest[cbor.RawMessage]{}
client.fingerprint = agent.getFingerprint()
View on GitHub (pinned to b38fb7dafa)
Solutions
- Set the environment variable, e.g. export HUB_URL=wss://hub.example.com, before starting the agent.
- If running under systemd, add Environment=HUB_URL=... to the unit file; for Docker use -e HUB_URL=... or an env_file.
- Check for typos in the variable name and that it is set in the same process/user that runs the agent.
- Fail fast at startup: validate required env vars before launching the service.
Example fix
// before ./agent # TOKEN set but HUB_URL missing -> error // after export HUB_URL="wss://hub.example.com" export TOKEN="..." ./agent
Defensive patterns
Strategy: validation
Validate before calling
if hubURL, ok := os.LookupEnv("HUB_URL"); !ok || hubURL == "" {
return fmt.Errorf("HUB_URL must be set (e.g. wss://hub.example.com)")
} Try / catch
client, err := newWebSocketClient(agent)
if err != nil {
if strings.Contains(err.Error(), "HUB_URL") {
log.Fatal("startup config incomplete: set HUB_URL, e.g. HUB_URL=wss://hub.example.com")
}
log.Fatal(err)
} Prevention
- Validate all required env vars (HUB_URL, TOKEN/TOKEN_FILE) at process startup with fail-fast.
- Use an env-file or secret manager so the variable ships with every deployment.
- Add a startup smoke test in CI that runs the agent with expected env config.
- Watch out for typos: HUB_URL vs HUBURL vs HUB_URl.
When it happens
Trigger: The agent is started (Start or newWebSocketClient directly) without HUB_URL exported in the process environment; also triggered by the listed tests when the variable is not seeded.
Common situations: Deploying via systemd/Docker/Kubernetes without passing the env var; running the agent binary from a shell where only TOKEN is set; typo like HUBURL or HUB_UR; config file not sourced before launch.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- must set TOKEN or TOKEN_FILE
- SSH disabled
- invalid signature - check KEY value
- data directory not found
- no websocket connection
AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31).
Data as JSON: /api/errors/5ac8b0839a6483d4.
Report an issue: GitHub.