NetrunHome

When something breaks

requirements.txt install error: why it happens and how to fix it

· 5 min read

In short

A requirements.txt install error is almost always caused by the file itself, not by the host. The number one cause is a file generated with pip freeze: it picks up lines pointing at folders on your own computer (the ones that look like @ file:///) and packages that do not exist in the public index. Next come pinned versions that do not exist for the Python version used during the build, Windows-only packages and stray characters in the file. The fix is the same in every case: rewrite requirements.txt by hand with only the libraries your code actually imports, and drop pins you do not need.

A requirements.txt install error looks equally alarming on every host: a long wall of output, a line saying could not find a version that satisfies the requirement somewhere in the middle, and a build that stops. The good news is that the host and your code are usually innocent. The list of libraries is the problem, and most of the time it was generated automatically and picked up things that should not be there.

The usual way to debug this is blind: log into a server, install packages by hand, try again, and hope you catch the moment it works. In Netrun the build log is visible in your dashboard in real time and it names the package and the line that stopped the build, so the fix comes down to one or two edits. Below are the causes ordered by how often they happen, and what to do about each one.

  1. Read the build log and find the package name#

    Do not read the whole output. Look at the last lines before the build stopped: they almost always name the package and the line number in requirements.txt, for example could not find a version that satisfies the requirement followed by a library name. In Netrun the build log streams into your dashboard, so there is nothing to download — just open the project. That package name is your diagnosis.

  2. Remove lines that point at folders on your computer#

    If the file came out of pip freeze, it often contains lines like package-name @ file:///Users/... or @ file:///C:/... — links to folders on your own machine. Those folders do not exist on a build server, so the install fails immediately. Delete everything after the @ sign and keep only the package name, or drop the whole line if you do not need that package. This is the single most common cause for anyone who generated the file automatically.

  3. Rebuild requirements.txt from your imports, not from freeze#

    pip freeze dumps everything installed in the environment: dev tools, dependencies of dependencies, libraries you tried once and forgot, and system packages that are not in the public index at all. Writing the file by hand is far more reliable: go through your source files, write down what you actually import, such as requests, flask or aiogram, and keep only that. A five-line file installs faster and breaks less often than a two-hundred-line one. Do not put the virtual environment folder into the archive — dependencies are installed during the build.

  4. Drop pinned versions that do not exist#

    A line like package==1.2.3 demands exactly that version. If that version was never released for the Python version used during the build, or it was pulled from the index, you get could not find a version that satisfies the requirement, usually followed by a list of versions that do exist. Remove the pin from the failing package or pick a version from that list. Conflicting pins work the same way: when two libraries demand different versions of a third one, nothing can satisfy both, so relax the pins that do not matter to you.

  5. Remove Windows-only packages and heavy builds#

    Libraries such as pywin32, pypiwin32 and windows-curses exist only on Windows and will never install on a Linux build server. Your code almost certainly does not import them — they came in with pip freeze, so delete them. A separate case is packages built from source that need system libraries: often it helps to unpin the version, because recent releases of popular libraries ship prebuilt Linux wheels, or to switch to a lighter library. If you really need that exact package, add your own Dockerfile that installs the system libraries — Netrun uses it instead of the automatic build.

  6. Check the file for stray characters, then upload a new version#

    The file must be plain text: one library per line, no non-Latin characters, no notes at the end of a line, no quotes and no extra spaces. Copying from a chat or an article breaks it surprisingly often: a normal hyphen turns into a dash, a normal space into a non-breaking one, and some editors save the file in their own encoding. Save it as plain UTF-8 text, upload the new version of the project and watch the log. If the build fails again, you already have the next package name and the loop repeats one line shorter.

One thing worth knowing while you fix this: a failed build does not break what is already running. A new version replaces the old one only after it builds successfully, so until then the link keeps answering, and your code, settings and secrets stay where they were. That means you can retry calmly, as many times as you need: the dashboard keeps the log of every attempt, so you can see whether the error moved on to the next package or stayed on the same one. Try Netrun.

Common questions

What does could not find a version that satisfies the requirement mean?

It means the installer went to the package index and found no version matching your line. Most often the pinned version does not exist for the Python version used during the build, or the package name has a typo. The error usually prints the versions that do exist right next to it, so pick one of those or remove the pin altogether.

Why does it install fine on my machine but fail on deploy?

On your machine many libraries are already installed from earlier projects, so the installer skips them and you never see the error. A build server starts from a clean environment: it installs exactly what the file lists, and one bad line stops everything. The Python version and the operating system used for the build can also differ from yours, so some packages from your environment simply do not exist there.

Should I pin package versions in requirements.txt?

Pinning is useful for a long-lived project where you want repeatable builds, but pinning everything from a pip freeze dump causes more trouble than it prevents. A practical middle ground is to pin the one or two libraries whose version really matters to you and leave the rest unpinned. Then a build never fails over the version of a package you do not even use.

What if a package needs compilation and system libraries?

First try removing the pin: recent releases of popular libraries usually ship prebuilt Linux wheels, so nothing has to be compiled. If system libraries are genuinely required, add a Dockerfile to your project that installs them and the platform will use it instead of the automatic build. Sometimes the simplest answer is a lighter library, for example parsing HTML without a browser.

Does a failed build break the project that is already running?

No. Until the new version builds successfully the previous one keeps running and the link answers as before. Your dashboard shows that publishing failed and what went wrong, and you can upload a corrected version as many times as you need.

What if there is no requirements.txt at all?

Create one: a plain text file in the project root with one library per line. List only what your code imports, and skip the standard Python modules such as os, json or datetime — they are already there. Without this file there is nothing to install from, and the project fails at startup with a message that a module was not found.

Can I run a Python project — Django, Flask or FastAPI?

Yes. Put your dependencies in requirements.txt — Netrun detects Python and builds the project for you. Django, Flask and FastAPI are supported; the app should listen on the port from the environment variable, and keys and database access are set as secrets rather than in the code.

Where can I see the logs and status of my project?

The project page shows the status, the logs and the event history — together they show what is happening with the project right now. The log view also reaches further back: scroll up and earlier lines load on their own.

How do I update the code of a project that is already published?

Open the project and upload a new version or update it from GitHub. The link stays the same, and your data is kept as long as it lives in persistent storage — the /data folder or a volume from your compose file.

Get your own project online

Upload your code, answer a couple of questions and get a working link. There is a free plan

Try Netrun
All blog articles