pallets/flask · error · RuntimeError
Unable to build URLs outside an active request without 'SERV
Error message
Unable to build URLs outside an active request without 'SERVER_NAME' configured. Also configure 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as needed.
What it means
Raised in `Flask.url_for()` (src/flask/app.py:1185) when URL building is attempted outside an active request and `create_url_adapter(None)` returns None because `SERVER_NAME` is not configured. Inside a request Flask derives host/scheme/root from the WSGI environ, but outside one it has no way to know the domain, so it needs `SERVER_NAME` (plus optionally `APPLICATION_ROOT` and `PREFERRED_URL_SCHEME`) to construct absolute URLs.
Source
Thrown at src/flask/app.py:1185
endpoint = f"{blueprint_name}{endpoint}"
else:
endpoint = endpoint[1:]
# When in a request, generate a URL without scheme and
# domain by default, unless a scheme is given.
if _external is None:
_external = _scheme is not None
else:
# If called by helpers.url_for, an app context is active,
# use its url_adapter. Otherwise, app.url_for was called
# directly, build an adapter.
if ctx is not None:
url_adapter = ctx.url_adapter
else:
url_adapter = self.create_url_adapter(None)
if url_adapter is None:
raise RuntimeError(
"Unable to build URLs outside an active request"
" without 'SERVER_NAME' configured. Also configure"
" 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as"
" needed."
)
# When outside a request, generate a URL with scheme and
# domain by default.
if _external is None:
_external = True
# It is an error to set _scheme when _external=False, in order
# to avoid accidental insecure URLs.
if _scheme is not None and not _external:
raise ValueError("When specifying '_scheme', '_external' must be True.")
self.inject_url_defaults(endpoint, values)
View on GitHub ↗ (pinned to 6a2f545bfd)
Solutions
- Set `app.config['SERVER_NAME'] = 'example.com'` (and `PREFERRED_URL_SCHEME = 'https'`, `APPLICATION_ROOT = '/'` as needed) so URL building works outside requests. Note SERVER_NAME also affects request routing/host matching — set it to your real public host.
- If you'd rather not set SERVER_NAME globally, wrap the call in a test request context: `with app.test_request_context(base_url='https://example.com/'): url = url_for(...)`.
- In tests, use `with app.test_request_context(): ...` around url_for calls.
- If the code actually runs during a request, ensure it executes inside the request (not in a spawned thread that lost the context).
Example fix
# before (background job)
link = url_for("confirm_email", token=token, _external=True) # RuntimeError
# after
app.config["SERVER_NAME"] = "example.com"
app.config["PREFERRED_URL_SCHEME"] = "https"
with app.app_context():
link = url_for("confirm_email", token=token, _external=True) Defensive patterns
Strategy: validation
Validate before calling
from flask import has_request_context
if not has_request_context() and not app.config.get('SERVER_NAME'):
raise RuntimeError('set SERVER_NAME (and APPLICATION_ROOT / PREFERRED_URL_SCHEME) before url_for outside a request') Type guard
def can_build_external_urls(app) -> bool:
from flask import has_request_context
return has_request_context() or bool(app.config.get('SERVER_NAME')) Prevention
- Set SERVER_NAME, APPLICATION_ROOT, and PREFERRED_URL_SCHEME in config for any app that builds URLs in CLI commands, Celery tasks, or emails
- Wrap background-job URL building in `with app.app_context():` after configuring SERVER_NAME
- Use `with app.test_request_context():` in tests that call url_for
When it happens
Trigger: Calling `url_for(...)` (or `app.url_for`) from a plain app context or none at all — e.g. inside a CLI command, background job, scheduler task, or when rendering an email template — with `app.config['SERVER_NAME']` unset.
Common situations: Celery/RQ workers and cron jobs generating links for emails; `flask shell` experiments; APScheduler tasks; sitemap or cache-warming scripts; tests calling url_for without `test_request_context`. Developers often hit it after refactoring link generation out of request handlers into background code.
Related errors
- The session is unavailable because no secret key was set. S
- The environment variable {variable_name!r} is not set and as
- 'static_folder' must be set to serve static_files.
- When specifying '_scheme', '_external' must be True.
- If an instance path is provided it must be absolute. A relat
AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31).
Data as JSON: /data/errors/f25b7ddf4532f854.json.
Report an issue: GitHub ↗.