| title | GitLab Runner β Prepare Environment: Exit Status 1 | |||||
|---|---|---|---|---|---|---|
| slug | gitlab-prepare-environment-exit-status-1 | |||||
| technologies |
|
|||||
| severity | high | |||||
| tags |
|
|||||
| related |
|
|||||
| last_reviewed | 2026-06-27 |
Preparing environment
Running on runner-abc123-project-456-concurrent-0 via gitlab-runner-host...
ERROR: Job failed (system failure): prepare environment: exit status 1.
Check https://docs.gitlab.com/runner/shells/index.html#shell-profile-loading for more information
prepare environment: exit status 1 is a system failure, not a script
failure. It happens during the runner's Preparing environment phase β before any
before_script/script runs β when the executor cannot set up the shell or
container in which the job will execute. The most common trigger on the shell
executor is a profile script (.bashrc, .bash_logout, .bash_profile) that
exits non-zero on login, which aborts the whole environment setup.
- gitlab (GitLab Runner, executor / login shell)
high β every job on the affected runner fails at setup, so the runner is effectively down for that project/group until fixed.
- A login-shell profile (
~/.bashrc,~/.bash_logout,/etc/profile.d/*) for thegitlab-runneruser runs a command that exits non-zero (e.g. an interactive-only command, anexit 1, or a tool that errors when no TTY). - The runner user's home directory is missing, unwritable, or owned by root.
- On Docker/Kubernetes executors, the image's entrypoint or a
pre_get_sourceshelper step fails (e.g. unwritable build dir). - Disk full or permissions prevent creating the build/cache directories.
- A broken
nvm/rbenv/conda init line in the profile that errors under a non-interactive login.
For the shell executor, GitLab Runner starts a login shell to run the
generated job script. A login shell sources the user's profile files. If any of
those sourced scripts returns a non-zero status (or a set -e profile hits an
error), the shell exits non-zero before the job script runs, and the runner
reports the failure as prepare environment: exit status 1. Because it happens in
the prepare phase, no job output appears β which is the tell that distinguishes it
from a normal exit code 1 script failure.
# Reproduce by opening a login shell as the runner user (read-only-ish probe)
sudo -u gitlab-runner bash -lc 'echo OK; echo "exit=$?"'
# Inspect the profile files that a login shell would source
ls -la /home/gitlab-runner/.bashrc /home/gitlab-runner/.bash_logout /home/gitlab-runner/.bash_profile
grep -nE 'exit|set -e|nvm|rbenv|conda' /home/gitlab-runner/.bashrc /etc/profile.d/*.sh 2>/dev/null
# Confirm home dir ownership/permissions and free disk
ls -ld /home/gitlab-runner
df -h /home/gitlab-runner
# Runner logs around the failure
journalctl -u gitlab-runner --since "15 min ago" --no-pager | tail -n 40# A broken profile reveals itself:
$ sudo -u gitlab-runner bash -lc 'echo OK'
nvm: command not found <- profile line errors
exit=127
# Healthy:
$ sudo -u gitlab-runner bash -lc 'echo OK'
OK
exit=0
-
Find the offending profile line and make it non-fatal / guard it for non-interactive shells:
# ~/.bashrc β bail out early when there is no interactive TTY case $- in *i*) ;; *) return 0;; esac
-
Remove or fix
exit 1, brokennvm/rbenvinit, or any command that errors without a TTY. -
Fix home-directory ownership and permissions:
sudo chown -R gitlab-runner:gitlab-runner /home/gitlab-runner. -
Free disk space if
dfshows the build volume full. -
For Docker/K8s executors, confirm the image entrypoint succeeds and the build directory is writable.
sudo -u gitlab-runner bash -lc 'echo OK' # must print OK and exit 0
# Re-run a pipeline; the "Preparing environment" phase completes and the job runs.- Keep
gitlab-runnerprofile files minimal and non-interactive-safe. - Monitor disk usage on runner build volumes and alert before full.
- Treat repeated
prepare environmentfailures as a runner-health alert, not a per-job retry.
gitlab Β· runner Β· executor Β· environment Β· production