windmill-labs/windmill · critical

BASE_INTERNAL_URL is required in agent mode

Error message

BASE_INTERNAL_URL is required in agent mode

What it means

In agent mode the binary acts as a remote agent that calls back to a Windmill server, so it must know the server's internally reachable address. `Mode` parsing in windmill-common panics when `MODE=agent` is set but `BASE_INTERNAL_URL` is unset — the agent cannot function without knowing where to reach the server.

Source

Thrown at backend/windmill-common/src/utils.rs:125

    pub static ref MODE_AND_ADDONS: ModeAndAddons = {
        let mut search_addon = false;
        let mode = std::env::var("MODE")
        .map(|x| x.to_lowercase())
        .map(|x| {
            if &x == "server" {
                println!("Binary is in 'server' mode");
                Mode::Server
            } else if &x == "worker" {
                tracing::info!("Binary is in 'worker' mode");
                #[cfg(windows)]
                {
                    println!("It is highly recommended to use the agent mode instead on windows (MODE=agent) and to pass a BASE_INTERNAL_URL");
                }
                Mode::Worker
            } else if &x == "agent" {
                println!("Binary is in 'agent' mode with BASE_INTERNAL_URL={}", std::env::var("BASE_INTERNAL_URL").unwrap_or_default());
                if std::env::var("BASE_INTERNAL_URL").is_err() {
                    panic!("BASE_INTERNAL_URL is required in agent mode")
                }
                if std::env::var("AGENT_TOKEN").is_err() {
                    println!("AGENT_TOKEN is not passed. This is required for the agent to work and contains the JWT to authenticate with the server.")
                }

                #[cfg(not(feature = "enterprise"))]
                {
                    panic!("Agent mode is only available in the EE, ignoring...");
                }
                #[cfg(feature = "enterprise")]
                Mode::Agent
            } else if &x == "indexer" {
                tracing::info!("Binary is in 'indexer' mode");
                #[cfg(not(feature = "tantivy"))]
                {
                    eprintln!("Cannot start the indexer because tantivy is not included in this binary/image. Make sure you are using the EE image if you want to access the full text search features.");
                    panic!("Indexer mode requires compiling with the tantivy feature flag.");
                }

View on GitHub (pinned to e474e8803c)

Solutions

  1. Set BASE_INTERNAL_URL to the server's address reachable from the agent (e.g. https://windmill.example.com)
  2. Also set AGENT_TOKEN — it is required for authentication and only warns if missing, but the agent will not work without it
  3. If you only need a worker and not an agent, use MODE=worker instead

Example fix

// before
MODE=agent
// after
MODE=agent
BASE_INTERNAL_URL=https://windmill.example.com
AGENT_TOKEN=<jwt>
Defensive patterns

Strategy: validation

Validate before calling

# preflight before launching in agent mode
if [ "$MODE" = "agent" ]; then
  [ -n "$BASE_INTERNAL_URL" ] || { echo "agent mode requires BASE_INTERNAL_URL" >&2; exit 1; }
  [ -n "$AGENT_TOKEN" ] || { echo "agent mode requires AGENT_TOKEN" >&2; exit 1; }
  curl -fsS "$BASE_INTERNAL_URL/api/health" >/dev/null || { echo 'BASE_INTERNAL_URL unreachable'; exit 1; }
fi

Prevention

When it happens

Trigger: Starting the binary with `MODE=agent` and no `BASE_INTERNAL_URL` environment variable defined.

Common situations: Deploying agents in EE setups and forgetting the env var; copying worker config to an agent without adding BASE_INTERNAL_URL; URL set only in a compose file that the agent container doesn't inherit.

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


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/83c6f244b703bcf3. Report an issue: GitHub.