HumanSignal/label-studio · error · ImproperlyConfigured

LABEL_STUDIO_HOST must be a subpath if DOMAIN_FROM_REQUEST i

Error message

LABEL_STUDIO_HOST must be a subpath if DOMAIN_FROM_REQUEST is True

What it means

When DOMAIN_FROM_REQUEST is enabled, Label Studio derives the external domain from incoming requests, so the static HOSTNAME (LABEL_STUDIO_HOST) may only be a subpath (must start with '/'). Settings loading raises ImproperlyConfigured at startup if HOSTNAME is set and does not start with '/'.

Source

Thrown at label_studio/core/settings/base.py:122

        # for django url resolver
        if HOSTNAME:
            # http[s]://domain.com:8080/script_name => /script_name
            pattern = re.compile(r'^http[s]?:\/\/([^:\/\s]+(:\d*)?)(.*)?')
            match = pattern.match(HOSTNAME)
            FORCE_SCRIPT_NAME = match.group(3)
            if FORCE_SCRIPT_NAME:
                logger.info('=> Django URL prefix is set to: %s', FORCE_SCRIPT_NAME)

FRONTEND_HMR = get_bool_env('FRONTEND_HMR', False)
FRONTEND_HOSTNAME = get_env('FRONTEND_HOSTNAME', 'http://localhost:8010' if FRONTEND_HMR else HOSTNAME)

DOMAIN_FROM_REQUEST = get_bool_env('DOMAIN_FROM_REQUEST', False)

if DOMAIN_FROM_REQUEST:
    # in this mode HOSTNAME can be only subpath
    if HOSTNAME and not HOSTNAME.startswith('/'):
        raise ImproperlyConfigured('LABEL_STUDIO_HOST must be a subpath if DOMAIN_FROM_REQUEST is True')


def _get_secure_proxy_ssl_header():
    value = get_env('SECURE_PROXY_SSL_HEADER')
    if not value:
        return None

    parts = [part.strip() for part in value.split(',')]
    if len(parts) != 2 or not all(parts):
        raise ImproperlyConfigured(
            'SECURE_PROXY_SSL_HEADER must be configured as "<header>,<value>", '
            'for example "HTTP_X_FORWARDED_PROTO,https".'
        )
    return tuple(parts)


SECURE_PROXY_SSL_HEADER = _get_secure_proxy_ssl_header()
USE_X_FORWARDED_HOST = get_bool_env('USE_X_FORWARDED_HOST', False)

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Set LABEL_STUDIO_HOST to a subpath only, starting with '/', e.g. LABEL_STUDIO_HOST=/label-studio.
  2. Or unset LABEL_STUDIO_HOST entirely when DOMAIN_FROM_REQUEST is true.
  3. Or set DOMAIN_FROM_REQUEST=false if you intend to serve a full absolute host.
  4. Review docker/k8s env files and remove conflicting host configuration.

Example fix

// before
DOMAIN_FROM_REQUEST=True
LABEL_STUDIO_HOST=https://myapp.example.com/ls
// after
DOMAIN_FROM_REQUEST=True
LABEL_STUDIO_HOST=/ls
Defensive patterns

Strategy: validation

Validate before calling

import os
dfr = os.environ.get('DOMAIN_FROM_REQUEST', '').lower() in ('1','true','yes','on')
host = os.environ.get('LABEL_STUDIO_HOST', '')
if dfr and host and not host.startswith('/'):
    raise SystemExit('LABEL_STUDIO_HOST must be a subpath (start with /) when DOMAIN_FROM_REQUEST is true')

Try / catch

try:
    # settings import triggers ImproperlyConfigured
    from django.conf import settings as s
    assert s.DOMAIN_FROM_REQUEST is not None
except ImproperlyConfigured as e:
    logger.error('Startup config invalid: %s', e)
    raise SystemExit(1)

Prevention

When it happens

Trigger: Starting Label Studio with DOMAIN_FROM_REQUEST=true and LABEL_STUDIO_HOST set to a full URL or non-slash value (e.g. 'https://example.com/ls' or 'ls') instead of a subpath like '/ls'.

Common situations: Migrating a deployment behind a reverse proxy to DOMAIN_FROM_REQUEST mode but leaving the old absolute LABEL_STUDIO_HOST value; copying settings between environments where DOMAIN_FROM_REQUEST differs.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/5e60e5a0979a5840. Report an issue: GitHub.