pallets/flask · error · ValueError
When specifying '_scheme', '_external' must be True.
Error message
When specifying '_scheme', '_external' must be True.
What it means
Raised by Flask.url_for() when _scheme is set but _external is False. Forcing a scheme only makes sense for absolute (external) URLs; allowing scheme + internal would silently produce insecure/misleading URLs, so Flask rejects it explicitly.
Solutions
- Set _external=True when using _scheme: url_for('endpoint', _scheme='https', _external=True).
- Drop _scheme if you want a relative/internal URL.
- Configure PREFERRED_URL_SCHEME in app config for default scheme instead of per-call _scheme.
Example fix
// before
url_for('login', _scheme='https', _external=False) # raises
// after
url_for('login', _scheme='https', _external=True) Defensive patterns
Strategy: validation
Validate before calling
if scheme is not None and external is False:
raise ValueError('_external must be True when _scheme is set')
url_for('endpoint', _scheme=scheme, _external=external) Type guard
def scheme_external_compatible(scheme, external) -> bool:
return scheme is None or external is True or external is None Try / catch
try:
url = url_for('endpoint', _scheme=scheme, _external=external)
except ValueError as e:
if '_external' in str(e):
external = True
url = url_for('endpoint', _scheme=scheme, _external=external)
raise Prevention
- Treat _scheme and _external as coupled: set both together.
- Prefer PREFERRED_URL_SCHEME config for default scheme.
- Wrap url_for helpers to enforce the invariant.
When it happens
Trigger: Calling url_for('endpoint', _scheme='https', _external=False) — scheme present but external explicitly disabled.
Common situations: Copy-paste of url_for args where _external was set to False for a relative link while keeping a _scheme; partial migration of http->https link logic.
Related errors
- Unable to build URLs outside an active request without…
- A valid Flask application was not obtained from
- Allowed methods must be a list of strings, for example…
- Could not import .
- Could not locate a Flask application. Use the 'flask --app'…
AI-assisted analysis of pallets/flask@3596b1ab61 (2026-08-11).
Data as JSON: /api/errors/8d06427abfec2385.
Report an issue: GitHub.
Appendix: source
Thrown at src/flask/app.py:1203
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)
try:
rv = url_adapter.build( # type: ignore[union-attr]
endpoint,
values,
method=_method,
url_scheme=_scheme,
force_external=_external,
)
except BuildError as error:
values.update(
_anchor=_anchor, _method=_method, _scheme=_scheme, _external=_external
)
return self.handle_url_build_error(error, endpoint, values)
if _anchor is not None:View on GitHub (pinned to 3596b1ab61)