{"record":{"id":"5e60e5a0979a5840","repo":"HumanSignal/label-studio","slug":"label-studio-host-must-be-a-subpath-if-domain-from","errorCode":null,"errorMessage":"LABEL_STUDIO_HOST must be a subpath if DOMAIN_FROM_REQUEST is True","messagePattern":"LABEL_STUDIO_HOST must be a subpath if DOMAIN_FROM_REQUEST is True","errorType":"exception","errorClass":"ImproperlyConfigured","httpStatus":null,"severity":"error","filePath":"label_studio/core/settings/base.py","lineNumber":122,"sourceCode":"\n        # for django url resolver\n        if HOSTNAME:\n            # http[s]://domain.com:8080/script_name => /script_name\n            pattern = re.compile(r'^http[s]?:\\/\\/([^:\\/\\s]+(:\\d*)?)(.*)?')\n            match = pattern.match(HOSTNAME)\n            FORCE_SCRIPT_NAME = match.group(3)\n            if FORCE_SCRIPT_NAME:\n                logger.info('=> Django URL prefix is set to: %s', FORCE_SCRIPT_NAME)\n\nFRONTEND_HMR = get_bool_env('FRONTEND_HMR', False)\nFRONTEND_HOSTNAME = get_env('FRONTEND_HOSTNAME', 'http://localhost:8010' if FRONTEND_HMR else HOSTNAME)\n\nDOMAIN_FROM_REQUEST = get_bool_env('DOMAIN_FROM_REQUEST', False)\n\nif DOMAIN_FROM_REQUEST:\n    # in this mode HOSTNAME can be only subpath\n    if HOSTNAME and not HOSTNAME.startswith('/'):\n        raise ImproperlyConfigured('LABEL_STUDIO_HOST must be a subpath if DOMAIN_FROM_REQUEST is True')\n\n\ndef _get_secure_proxy_ssl_header():\n    value = get_env('SECURE_PROXY_SSL_HEADER')\n    if not value:\n        return None\n\n    parts = [part.strip() for part in value.split(',')]\n    if len(parts) != 2 or not all(parts):\n        raise ImproperlyConfigured(\n            'SECURE_PROXY_SSL_HEADER must be configured as \"<header>,<value>\", '\n            'for example \"HTTP_X_FORWARDED_PROTO,https\".'\n        )\n    return tuple(parts)\n\n\nSECURE_PROXY_SSL_HEADER = _get_secure_proxy_ssl_header()\nUSE_X_FORWARDED_HOST = get_bool_env('USE_X_FORWARDED_HOST', False)","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/core/settings/base.py#L104-L140","documentation":"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 '/'.","triggerScenarios":"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'.","commonSituations":"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.","solutions":["Set LABEL_STUDIO_HOST to a subpath only, starting with '/', e.g. LABEL_STUDIO_HOST=/label-studio.","Or unset LABEL_STUDIO_HOST entirely when DOMAIN_FROM_REQUEST is true.","Or set DOMAIN_FROM_REQUEST=false if you intend to serve a full absolute host.","Review docker/k8s env files and remove conflicting host configuration."],"exampleFix":"// before\nDOMAIN_FROM_REQUEST=True\nLABEL_STUDIO_HOST=https://myapp.example.com/ls\n// after\nDOMAIN_FROM_REQUEST=True\nLABEL_STUDIO_HOST=/ls","handlingStrategy":"validation","validationCode":"import os\ndfr = os.environ.get('DOMAIN_FROM_REQUEST', '').lower() in ('1','true','yes','on')\nhost = os.environ.get('LABEL_STUDIO_HOST', '')\nif dfr and host and not host.startswith('/'):\n    raise SystemExit('LABEL_STUDIO_HOST must be a subpath (start with /) when DOMAIN_FROM_REQUEST is true')","typeGuard":null,"tryCatchPattern":"try:\n    # settings import triggers ImproperlyConfigured\n    from django.conf import settings as s\n    assert s.DOMAIN_FROM_REQUEST is not None\nexcept ImproperlyConfigured as e:\n    logger.error('Startup config invalid: %s', e)\n    raise SystemExit(1)","preventionTips":["Document the DOMAIN_FROM_REQUEST/LABEL_STUDIO_HOST pairing in deployment docs.","Use env templates that comment out LABEL_STUDIO_HOST when DOMAIN_FROM_REQUEST=true.","Smoke-test startup in staging after changing domain settings.","Keep only one source of truth for the external host."],"tags":["configuration","django","improperlyconfigured","deployment"],"backgroundTag":"conflicting-settings","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}