{"record":{"id":"7dc70393cb161b9c","repo":"reflex-dev/reflex","slug":"the-upload-did-not-finish-before-its-window-closed","errorCode":null,"errorMessage":"the upload did not finish before its window closed; this usually means the connection is too slow for the size of the build","messagePattern":"the upload did not finish before its window closed; this usually means the connection is too slow for the size of the build","errorType":"exception","errorClass":"ArchiveUploadError","httpStatus":null,"severity":"error","filePath":"packages/reflex-hosting-cli/src/reflex_cli/utils/hosting.py","lineNumber":2254,"sourceCode":"            raise ArchiveUploadError(\n                f\"could not reach the deployment service: {ex}\"\n            ) from ex\n        if reservation is None:\n            return None\n        try:\n            _put_reserved_archives(zip_dir, reservation, sizes)\n        except httpx.HTTPStatusError as ex:\n            if ex.response.status_code != HTTPStatus.FORBIDDEN:\n                raise ArchiveUploadError(\n                    f\"could not upload the build to storage: HTTP {ex.response.status_code}\"\n                ) from ex\n            if attempt < UPLOAD_ATTEMPTS - 1:\n                logger.warning(\"the upload window expired; reserving another one\")\n        except httpx.HTTPError as ex:\n            raise ArchiveUploadError(f\"could not upload the build: {ex}\") from ex\n        else:\n            return reservation[\"deployment_id\"]\n    raise ArchiveUploadError(\n        \"the upload did not finish before its window closed; this usually means \"\n        \"the connection is too slow for the size of the build\"\n    )\n\n\ndef create_deployment(\n    zip_dir: Path,\n    client: AuthenticatedClient,\n    app_name: str | None,\n    project_id: str | None,\n    regions: list | None,\n    hostname: str | None,\n    vmtype: str | None,\n    secrets: dict | None,\n    packages: list | None,\n    strategy: str | None,\n    app_id: str | None,\n    description: str | None = None,","sourceCodeStart":2236,"sourceCodeEnd":2272,"githubUrl":"https://github.com/reflex-dev/reflex/blob/45b8ed5ab735f8a56bbb09a42384f030eb0208e7/packages/reflex-hosting-cli/src/reflex_cli/utils/hosting.py#L2236-L2272","documentation":"Raised after all UPLOAD_ATTEMPTS iterations fail: every storage PUT returned 403 FORBIDDEN, meaning the presigned upload window expired before the transfer completed each time. The message explains this usually indicates the connection is too slow for the build size.","triggerScenarios":"Each attempt to PUT the archives gets a 403 because the presigned URL's time window lapsed mid-upload; happens repeatedly with large builds on slow connections.","commonSituations":"Uploading hundreds of MB on slow uplinks; proxies adding latency; huge static assets bundled into .web.","solutions":["Reduce the deployment bundle size (remove large files from .web/static, compress assets)","Upgrade connection speed or switch networks, then redeploy","Update reflex-hosting-cli — newer versions may chunk uploads or extend windows","If the build genuinely must be large, contact Reflex hosting support for raised limits"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"import os\nbuild_mb = get_dir_size('.web') / 1e6\nif build_mb > 100:\n    warn('large bundle; upload window may expire on slow links')","typeGuard":null,"tryCatchPattern":"try:\n    upload_archives(...)\nexcept ArchiveUploadError as ex:\n    if 'upload did not finish before its window closed' in str(ex):\n        strip_large_assets(); retry()","preventionTips":["Prune large static assets before deploying","Compress images and remove dev files from .web","Upgrade the CLI for improved upload chunking"],"tags":["upload","deployment","timeout","presigned-url","slow-network"],"backgroundTag":"presigned-url-expired","analyzedSha":"45b8ed5ab735f8a56bbb09a42384f030eb0208e7","analyzedAt":"2026-08-28T19:25:27.644Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}