pallets/flask · error · RuntimeError

'static_folder' must be set to serve static_files.

Error message

'static_folder' must be set to serve static_files.

What it means

Raised by `send_static_file()` (src/flask/app.py:405) when `has_static_folder` is false, i.e. the app or blueprint was created with `static_folder=None`. Flask only registers and serves the static view when a static folder is configured, so requesting a static file without one is a programming/configuration error, not a 404.

Source

Thrown at src/flask/app.py:405

        if isinstance(value, timedelta):
            return int(value.total_seconds())

        return value  # type: ignore[no-any-return]

    def send_static_file(self, filename: str) -> Response:
        """The view function used to serve files from
        :attr:`static_folder`. A route is automatically registered for
        this view at :attr:`static_url_path` if :attr:`static_folder` is
        set.

        Note this is a duplicate of the same method in the Flask
        class.

        .. versionadded:: 0.5

        """
        if not self.has_static_folder:
            raise RuntimeError("'static_folder' must be set to serve static_files.")

        # send_file only knows to call get_send_file_max_age on the app,
        # call it here so it works for blueprints too.
        max_age = self.get_send_file_max_age(filename)
        return send_from_directory(
            t.cast(str, self.static_folder), filename, max_age=max_age
        )

    def open_resource(
        self, resource: str, mode: str = "rb", encoding: str | None = None
    ) -> t.IO[t.AnyStr]:
        """Open a resource file relative to :attr:`root_path` for reading.

        For example, if the file ``schema.sql`` is next to the file
        ``app.py`` where the ``Flask`` app is defined, it can be opened
        with:

        .. code-block:: python

View on GitHub ↗ (pinned to 6a2f545bfd)

Solutions

  1. Pass `static_folder='static'` (and optionally `static_url_path`) when constructing the `Flask` app or `Blueprint`.
  2. For blueprints, remember the static folder path is relative to the blueprint's `root_path` — verify the directory actually exists.
  3. If the app is intentionally API-only, remove the `url_for('static', ...)` references or the direct `send_static_file` call instead of re-enabling static serving.
  4. For one-off files outside a static folder, use `flask.send_from_directory(directory, filename)` directly.

Example fix

# before
bp = Blueprint("admin", __name__)

# after
bp = Blueprint("admin", __name__, static_folder="static", static_url_path="/admin/static")
Defensive patterns

Strategy: validation

Validate before calling

if app.static_folder is None:
    raise RuntimeError('configure static_folder before calling send_static_file')

Type guard

def has_static_folder(app) -> bool:
    return app.static_folder is not None

Prevention

When it happens

Trigger: Calling `app.send_static_file(name)` or `blueprint.send_static_file(name)` directly (or via `url_for('static', ...)` hitting the static endpoint) on a `Flask(__name__, static_folder=None)` app or a `Blueprint(...)` created without a `static_folder` argument (blueprints default to None, unlike the app).

Common situations: Blueprints are the classic case — developers assume blueprints serve static files like the app does, but `Blueprint` has no default static folder. Also hit when disabling static serving for API-only apps (`static_folder=None`) while templates still call `url_for('static', ...)`, or when a custom view delegates to `send_static_file`.

Related errors


AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31). Data as JSON: /data/errors/659cfdf18dc82304.json. Report an issue: GitHub ↗.