{"record":{"id":"01e629a8fc90394c","repo":"HumanSignal/label-studio","slug":"debugging-info-is-not-available-for-s3-endpoints-o","errorCode":null,"errorMessage":"Debugging info is not available for s3 endpoints on domain: {domain}. Please contact your Label Studio devops team if you require detailed error reporting for this domain.","messagePattern":"Debugging info is not available for s3 endpoints on domain: (.+?)\\. Please contact your Label Studio devops team if you require detailed error reporting for this domain\\.","errorType":"exception","errorClass":"S3StorageError","httpStatus":null,"severity":"warning","filePath":"label_studio/io_storages/s3/utils.py","lineNumber":173,"sourceCode":"# prevents network call on first use\nextractor = TLDExtract(suffix_list_urls=())\n\n\ndef catch_and_reraise_from_none(func):\n    \"\"\"\n    For S3 storages - if s3_endpoint is not on a known domain, catch exception and\n    raise a new one with the previous context suppressed. See also: https://peps.python.org/pep-0409/\n    \"\"\"\n\n    def wrapper(self, *args, **kwargs):\n        try:\n            return func(self, *args, **kwargs)\n        except Exception as e:\n            if self.s3_endpoint and (\n                domain := extractor.extract_urllib(urlparse(self.s3_endpoint)).registered_domain.lower()\n            ) not in [trusted_domain.lower() for trusted_domain in settings.S3_TRUSTED_STORAGE_DOMAINS]:\n                logger.error(f'Exception from unrecognized S3 domain: {e}', exc_info=True)\n                raise S3StorageError(\n                    f'Debugging info is not available for s3 endpoints on domain: {domain}. '\n                    'Please contact your Label Studio devops team if you require detailed error reporting for this domain.'\n                ) from None\n            else:\n                raise e\n\n    return wrapper\n","sourceCodeStart":155,"sourceCodeEnd":181,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/io_storages/s3/utils.py#L155-L181","documentation":"A decorator (`wrapper`) in label_studio/io_storages/s3/utils.py intercepts exceptions from S3 storage methods. If the storage uses a custom s3_endpoint whose registered domain is not in settings.S3_TRUSTED_STORAGE_DOMAINS, the original exception is replaced by S3StorageError saying debugging info is unavailable — this prevents leaking internal endpoint/error details of untrusted third-party S3 services to end users.","triggerScenarios":"Any S3 storage operation (sync, validate_connection, etc.) that raises while s3_endpoint is set to a host whose registered domain is not listed in S3_TRUSTED_STORAGE_DOMAINS — the `from None` suppresses the original cause entirely.","commonSituations":"Self-hosted MinIO/DigitalOcean Spaces/Wasabi endpoints without adding their domain to the trusted list; misconfigured s3_endpoint with a typo domain; operators unaware S3_TRUSTED_STORAGE_DOMAINS exists.","solutions":["Add your endpoint's registered domain to settings.S3_TRUSTED_STORAGE_DOMAINS (e.g. ['minio.mycompany.com']) to get full error reporting.","Fix the s3_endpoint value if the domain is a typo.","Reproduce the underlying error from the server logs — logger.error('Exception from unrecognized S3 domain: ...') still records the real exception server-side.","If you don't need a custom endpoint, unset s3_endpoint and use standard AWS S3."],"exampleFix":"// before (settings)\nS3_TRUSTED_STORAGE_DOMAINS = []\n\n// after\nS3_TRUSTED_STORAGE_DOMAINS = ['minio.mycompany.com']","handlingStrategy":"try-catch","validationCode":"from urllib.parse import urlparse\nimport tldextract\nfrom django.conf import settings\n\ndef endpoint_domain_is_trusted(s3_endpoint: str) -> bool:\n    domain = tldextract.extract(urlparse(s3_endpoint)).registered_domain.lower()\n    trusted = [d.lower() for d in settings.S3_TRUSTED_STORAGE_DOMAINS]\n    return domain in trusted\n\nif storage_config.get('s3_endpoint') and not endpoint_domain_is_trusted(storage_config['s3_endpoint']):\n    print('Warning: errors from this endpoint will be masked; add domain to S3_TRUSTED_STORAGE_DOMAINS')","typeGuard":"def is_configured_endpoint(endpoint) -> bool:\n    return isinstance(endpoint, str) and endpoint.startswith(('http://', 'https://'))","tryCatchPattern":"try:\n    storage.sync()\nexcept S3StorageError as e:\n    if 'Debugging info is not available' in str(e):\n        # real cause is in server logs under 'Exception from unrecognized S3 domain'\n        # permanent fix: add the endpoint domain to settings.S3_TRUSTED_STORAGE_DOMAINS\n        logger.error('Masked S3 error for untrusted endpoint domain')","preventionTips":["Add every self-hosted/S3-compatible endpoint domain to S3_TRUSTED_STORAGE_DOMAINS at deploy time.","Keep the trusted list synced across environments (dev/staging/prod).","Check server logs for the original exception when this masked error appears.","Avoid typos in s3_endpoint — an unintended domain silently downgrades error reporting."],"tags":["s3","security","endpoint","configuration","error-masking"],"backgroundTag":"untrusted-endpoint-domain","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}