home-assistant/core · error · BackupAgentError

Upload timed out after {UPLOAD_TIMEOUT} seconds

Error message

Upload timed out after {UPLOAD_TIMEOUT} seconds

What it means

BackupAgentError raised in the B2 upload path when the bucket.upload_file(...) future exceeds UPLOAD_TIMEOUT seconds. The read stream is aborted (reader.abort()), an error is logged with the filename and the timeout value, and the timeout re-raises as BackupAgentError via 'raise ... from None' (TimeoutError is not chained).

Source

Thrown at homeassistant/components/backblaze_b2/backup.py:371

        _LOGGER.debug("Uploading backup file %s with streaming", filename)
        try:
            content_type, _ = mimetypes.guess_type(filename)
            file_version = await asyncio.wait_for(
                self._hass.async_add_executor_job(
                    self._upload_unbound_stream_sync,
                    reader,
                    filename,
                    content_type or "application/x-tar",
                    file_info,
                ),
                timeout=UPLOAD_TIMEOUT,
            )
        except TimeoutError:
            _LOGGER.error(
                "Upload of %s timed out after %s seconds", filename, UPLOAD_TIMEOUT
            )
            reader.abort()
            raise BackupAgentError(
                f"Upload timed out after {UPLOAD_TIMEOUT} seconds"
            ) from None
        except asyncio.CancelledError:
            _LOGGER.warning("Upload of %s was cancelled", filename)
            reader.abort()
            raise
        finally:
            reader.close()

        _LOGGER.debug("Successfully uploaded %s (ID: %s)", filename, file_version.id_)

    @handle_b2_errors
    @override
    async def async_delete_backup(self, backup_id: str, **kwargs: Any) -> None:
        """Delete a backup and its associated metadata file from Backblaze B2."""
        file, metadata_file = await self._find_file_and_metadata_version_by_id(
            backup_id
        )

View on GitHub (pinned to 58a3fdb3ea)

Solutions

  1. Retry the backup during low network usage; the abort cleans the partial upload
  2. Reduce backup size (exclude media or use a partial backup)
  3. Check upstream bandwidth stability (a stalled, not merely slow, connection also trips the fixed timeout)
  4. If recurring, file an issue proposing a configurable/bandwidth-aware timeout; the constant is fixed in code
Defensive patterns

Strategy: retry

Validate before calling

# pre-flight: estimate upload time vs fixed timeout
estimated_seconds = backup.size * 8 / (uplink_bits_per_sec * 0.8)
if estimated_seconds > UPLOAD_TIMEOUT:
    # exclude data or split the backup before starting

Type guard

def is_upload_timeout(err: BaseException) -> bool:
    from homeassistant.components.backup.exceptions import BackupAgentError
    return isinstance(err, BackupAgentError) and "timed out" in str(err)

Try / catch

try:
    await asyncio.wait_for(upload_future, timeout=UPLOAD_TIMEOUT)
except TimeoutError:
    reader.abort()
    raise BackupAgentError(f"Upload timed out after {UPLOAD_TIMEOUT} seconds") from None

Prevention

When it happens

Trigger: asyncio.wait_for-style timeout around the executor upload future fires: the upload of the backup tar to B2 did not complete within UPLOAD_TIMEOUT, typically because of insufficient bandwidth for the backup size or a stalled connection.

Common situations: Large backups on slow uplinks (e.g. tens of GB on ADSL), throttled connections, VPN/proxy stalling large streams, B2 transient slowness.

Understand the failure class

Related errors


AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14). Data as JSON: /api/errors/18bb31b2f24127a8. Report an issue: GitHub.