# Classify and fix Streamlit Community Cloud deployment failures
Use this when an app runs locally but fails on Streamlit Community Cloud
(share.streamlit.io), or when a deployed app that used to work now shows an
error page. Don't change code until you've classified the failure from the
app's logs: the app owner opens them from the "Manage app" menu (bottom-right
of the deployed app). Match what you see against the four signatures below.
## 1. The four signatures
- **A. Dependency failure at build time.** Log lines: `❗️ installer returned a
non-zero exit code` / `❗️ Error during processing dependencies! Please fix
the error and push an update, or try restarting the app.` The app never
starts.
- **B. Runtime crash after start.** The app builds, then shows "Oh no. Error
running app.", or the log says `❗️ Streamlit server consistently failed
status checks` / `❗️ Please fix the errors, push an update to the git repo,
or reboot the app.` The traceback in the logs names the real exception.
- **C. Resource exhaustion.** The app shows "This app has gone over its
resource limits." Community Cloud gives each app 1 GB of RAM; exceeding it
kills the app, often mid-session.
- **D. Secrets/config missing.** Works locally, fails on Cloud with a
`KeyError` from `st.secrets[...]` or a connection error to a private
service.
## 2. Fix A: dependency install failures
- `requirements.txt` is the supported path; pin versions (`pandas==2.2.3`) so a
fresh solve can't drift. A common failure: a package that installs fine
locally fails on Cloud because the local machine had a cached wheel or a
system library the Cloud image lacks.
- `environment.yml` (conda) is a frequent trap: the conda solver can exhaust
the 1 GB build memory and get OOM-killed (`bash: line 3: 11 Killed ...
conda env update`), even for packages pip would install fine. Prefer
`requirements.txt`; use conda only if a package truly has no pip wheel.
- Non-Python system libraries (e.g. `libgl1` for OpenCV, `tesseract-ocr`) go
in `packages.txt` at the repo root — one apt package name per line. They are
installed with apt before pip runs.
- Set the Python version under Advanced settings at deploy time, and reproduce
failures locally with that same version.
## 3. Fix B: runtime crashes
- Read the traceback in the logs, not the "Oh no" page. It usually names a
missing file, a wrong relative path (the working directory on Cloud is the
repo root; on your machine you may have run Streamlit from a subfolder), or
an unhandled exception in a code path local testing never hit.
- Pushing a fix redeploys automatically. If the app looks stuck after a push,
reboot from the ⋮ menu → "Reboot app".
## 4. Fix C: over resource limits
Rebooting clears it temporarily; the fix is using less memory:
- Don't hold the full raw dataset in memory. Downcast dtypes (`object` →
`category`, `float64` → `float32`), drop unused columns, aggregate before
caching.
- Give caches a `ttl` so stale entries expire instead of accumulating:
`@st.cache_data(ttl=3600)`.
- Load heavy artifacts (model weights) once via `@st.cache_resource`, not once
per session.
- If the *dependency install itself* gets killed, that's signature A, not C —
fix the environment, not the code.
## 5. Fix D: secrets
- Never commit `.streamlit/secrets.toml` — add it to `.gitignore`. On Cloud,
paste the file's TOML contents into the "Secrets" field under Advanced
settings while deploying; for an already-deployed app, go to the workspace,
the app's ⋮ menu → Settings → Secrets. The app restarts and picks them up.
- Read secrets in code through indirection, and fail legibly when one is
absent:
```python
import streamlit as st
value = st.secrets.get("api_key")
if not value:
st.error("Missing 'api_key' in app secrets (workspace → app ⋮ → Settings → Secrets).")
st.stop()
```
## 6. Checklist
1. Open the logs (Manage app) and match the signature: dependency (A), runtime
(B), resources (C), secrets (D).
2. A → pin `requirements.txt`, drop conda unless unavoidable, system libs in
`packages.txt`, match the Python version.
3. B → read the traceback; check relative paths and untested code paths.
4. C → reboot is triage; shrink memory (dtypes, `ttl`, lazy loads) for the
cure.
5. D → secrets via app settings, never committed; `.gitignore` the local file.