Phoenix "** (RuntimeError) SECRET_KEY_BASE missing" in CI
Phoenix's generated config/runtime.exs requires SECRET_KEY_BASE in prod. When a prod build, release, or prod-env task runs in CI without it set, runtime config raises before the app can start.
What this error means
A MIX_ENV=prod build, mix release, or mix phx.gen.release step fails with "** (RuntimeError) environment variable SECRET_KEY_BASE is missing".
** (RuntimeError) environment variable SECRET_KEY_BASE is missing.
You can generate one by calling: mix phx.gen.secret
(my_app 0.1.0) config/runtime.exs:24: MyApp.Config.fetch/0Common causes
runtime.exs requires the secret in prod
The default Phoenix runtime.exs calls System.fetch_env!("SECRET_KEY_BASE") under prod, which raises when the variable is unset.
CI builds prod without providing the secret
A release or prod compile step runs without SECRET_KEY_BASE in the environment, so runtime config fails at load.
How to fix it
Provide SECRET_KEY_BASE from a secret
- Generate a value with
mix phx.gen.secret(store it as a repo/org secret). - Expose it in the env of the prod/release step.
- Re-run the build.
- run: mix release
env:
MIX_ENV: prod
SECRET_KEY_BASE: ${{ secrets.SECRET_KEY_BASE }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}Guard config that is only needed at boot
If a step only compiles (not boots) prod, gate runtime-only requirements so compilation does not demand runtime secrets.
if config_env() == :prod do
secret_key_base = System.fetch_env!("SECRET_KEY_BASE")
# ...
endHow to prevent it
- Store SECRET_KEY_BASE as a CI secret and inject it into prod steps.
- Keep runtime-only requirements inside config_env() == :prod.
- Provide DATABASE_URL and other prod env vars for release builds.