Runner CLI flags
Most flags have a corresponding environment variable. When both are set, the flag takes precedence. Duration flags take minutes or seconds on the CLI, but the paired environment variable is always in milliseconds, indicated by the _MS suffix, and the Default column shows the flag's unit: --exit-if-unused-min 10 is equivalent to SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000, and a Helm value like SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15" means 15 milliseconds, not the 15-minute default.
| Flag | Env var | Default | Description |
|---|---|---|---|
--api-url <url> | none | https://api.anthropic.com | API base URL. Override only for testing. |
--base-dir <path> | SELF_HOSTED_RUNNER_BASE_DIR | /workspace; none on Windows | Directory for repository checkouts and per-session working directories. The runner needs write access to this path or its parent. The runner creates the directory at startup and exits with cannot create or write to base directory when it can't create or write to it. Before v2.1.225, the runner created the directory when the first session started, so an unusable path failed sessions rather than startup. On Windows, which isn't a supported runner host, there is no default: the runner exits at startup unless you pass the flag or set the variable. Use the same value on every runner in an environment. See Keep the base directory and capacity identical across runners. |
--capacity <n> | none | 1 | Maximum concurrent sessions this runner handles. All sessions belong to the same locked owner. Use the same value on every runner in an environment; see Keep the base directory and capacity identical across runners. |
--client-label <label> | SELF_HOSTED_RUNNER_CLIENT_LABEL | the host's hostname | Label the runner sends when it registers. The runner also reports it as the client_label label of claude_code_self_hosted_runner_info. Requires Claude Code v2.1.248 or later. |
--configure-git | SELF_HOSTED_RUNNER_CONFIGURE_GIT=1 | off | At startup, write global git identity, enable Anthropic commit signing, turn on git push negotiation, and install commit hooks that append a Co-authored-by: trailer. Push negotiation requires Claude Code v2.1.257 or later. See Configure git. |
--confine-repo-settings <mode> | SELF_HOSTED_RUNNER_CONFINE_REPO_SETTINGS | warn | Sets the mode of the guard that flags a session when a repository's committed settings try to grant write or read access outside that session's own workspace, set environment variables, or override the operator's sandbox or hooks posture, such as sandbox.enabled: false or disableAllHooks. The default warn logs the violation and still starts the session, enforce refuses the session, and off disables the scan. See Harden your deployment. |
--debug-token-dir <path> | SELF_HOSTED_RUNNER_DEBUG_TOKEN_DIR | unset | Write live tokens to disk for inspection. Debug only; don't use in production. |
--defer-shutdown-max-min <n> | SELF_HOSTED_RUNNER_DEFER_SHUTDOWN_MAX_MS | 0 | On the first SIGTERM or SIGINT, keep serving the sessions already attached instead of draining them, then release whatever is still attached N minutes later and exit. Raise your host's stop timeout before you set this. See Defer the drain past the first signal. 0 disables. Requires Claude Code v2.1.238 or later. |
--drain-grace-sec <n> | SELF_HOSTED_RUNNER_DRAIN_GRACE_MS | 0 | Until the runner receives a shutdown signal or reaches its retire time, controls when the runner exits after its active sessions finish: 0 exits immediately without polling for more, and a positive value keeps the runner alive and re-polling the locked owner's queue for that many seconds first, at the cost of the per-session container isolation described in the hardening section. After a first signal you deferred with --defer-shutdown-max-min, the runner exits as soon as it holds no sessions, whatever you set here. |
--drain-wait-sec <n> | SELF_HOSTED_RUNNER_DRAIN_WAIT_MS | 0 | Once the drain starts, which is on SIGTERM unless you set --defer-shutdown-max-min, wait up to N seconds for each session's in-flight turn and background tasks to finish before terminating the child. During this wait, the runner counts a background task that has just finished as still running until the follow-up turn that reads its result starts, for at most the SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS window. |
--environment-secret-file <path> | SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET | required | Path to a file containing the environment secret, or, for runners spawned by the orchestrator, the single-use work-order JWT. SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET carries the secret value directly, not a file path. The older --pool-secret-file flag and SELF_HOSTED_RUNNER_POOL_SECRET variable still work and print a deprecation notice to stderr; preview-program runner builds older than 2.1.216 only recognize those older names. |
--exec-path <path> | SELF_HOSTED_RUNNER_EXEC_PATH | own binary | Binary or wrapper script to spawn for each session. See Wrapper scripts. |
--exit-if-unused-min <n> | SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS | 0 | Exit after N minutes of polling with no work ever assigned, for autoscaler scale-down. 0 disables. |
--git-host-rewrite <from>=<to> | none | unset | Rewrite https://<from>/... source URLs to https://<to>/... before cloning, for split-horizon DNS. Repeatable; flag only. |
--git-ssh-rewrite <host> | none | unset | Rewrite https://<host>/... source URLs to git@<host>:... before cloning, for SSH-only git hosts. Repeatable; flag only. |
--health-port <port> | SELF_HOSTED_RUNNER_HEALTH_PORT | 8080 | Port for the /healthz and /metrics listener. Set 0 to disable. |
--hooks-dir <path> | SELF_HOSTED_RUNNER_HOOKS_DIR | unset | Directory of lifecycle hook scripts. See Lifecycle hooks. |
--kill-session-after-min <n> | SELF_HOSTED_RUNNER_MAX_LIFETIME_MS | 0 | Limit a session to N minutes wall-clock, as a safety limit for stuck sessions. On v2.1.260 or later, the runner releases a session that reaches the limit so it can resume on its user's next message, and terminates it only if it's still on the runner when the SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS grace window ends. Before v2.1.260, the runner terminated the session at the limit. See Some sessions don't count as idle for the details and how to choose a value. 0 disables. |
--lock-to-account <id> | SELF_HOSTED_RUNNER_LOCK_TO_ACCOUNT | unset | Pre-lock the runner to a specific account at startup instead of locking on first session. Accepts an email address or user_... ID in the environment's organization. A pre-locked runner never picks up Claude Tag channel sessions, which have no account. |
--log-file <path> | SELF_HOSTED_RUNNER_LOG_FILE | unset | Mirror runner logs to a file in addition to stdout and stderr, created with 0600 permissions. Required for self-hosted-runner doctor to tail logs locally. |
--log-level <level> | none | info | info or debug |
--post-session-hook-timeout-sec <n> | SELF_HOSTED_RUNNER_POST_SESSION_HOOK_TIMEOUT_MS | 60 | Budget for the post-session hook on every session end, including runner shutdown |
--proxy-authorization-command <command> | SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_COMMAND | unset | Shell command the runner runs for every connection to your egress proxy, using its trimmed stdout as the Proxy-Authorization header value. Requires HTTPS_PROXY or HTTP_PROXY, and can't be combined with --proxy-authorization-file. See Authenticate to an egress proxy. Requires Claude Code v2.1.238 or later. |
--proxy-authorization-file <path> | SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_FILE | unset | File the runner reads for every connection to your egress proxy, using its trimmed contents as the Proxy-Authorization header value. Use this flag for a token another process rotates in place. Carries the same requirements as --proxy-authorization-command, and can't be combined with it. See Authenticate to an egress proxy. Requires Claude Code v2.1.238 or later. |
--push-outcome-on-release | SELF_HOSTED_RUNNER_PUSH_OUTCOME_ON_RELEASE | off | On a runner-initiated session end such as a drain or idle release, push tracked outcome branches to origin before deleting the workspace, so in-flight commits survive a restart. Best-effort; adds 30 seconds to the shutdown budget, and requires git 2.29 or newer to resume from the pushed branch. Restrict push access to claude/* refs before enabling; see Resumed sessions lose unpushed work. Repositories checked out via a checkout lifecycle hook aren't pushed; snapshot those from the post-session hook instead. |
--release-idle-session-min <n> | SELF_HOSTED_RUNNER_SESSION_IDLE_MS | 0 | Release a session slot after N minutes of inactivity once a turn finishes or the session waits for the user's action. A session that's still mid-turn, including one holding a never-finishing background task or an approval requested from inside a running tool call, doesn't count as idle; pair with --kill-session-after-min as the hard backstop. After a session's background task finishes, the runner considers the session busy until the follow-up turn that reads the result starts, for at most the SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS window. Until the runner receives a shutdown signal or reaches its retire time, a release that leaves the runner with no active sessions starts the same exit path as a normal drain, governed by --drain-grace-sec. After a first signal you deferred with --defer-shutdown-max-min, the runner exits as soon as a release leaves it holding no sessions. 0 disables. |