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
- Retry the backup during low network usage; the abort cleans the partial upload
- Reduce backup size (exclude media or use a partial backup)
- Check upstream bandwidth stability (a stalled, not merely slow, connection also trips the fixed timeout)
- 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
- Measure uplink bandwidth and size backups to finish within the fixed timeout
- Use partial backups to cut size on slow connections
- Retry at off-peak hours; the reader.abort() cleanup prevents partial-file residue
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
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Failed during {func.__name__}: {err}
- Backup {backup_id} not found
- Failed to upload backup
- Timeout during backup operation in {func.__name__}
- invalid_credentials
AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14).
Data as JSON: /api/errors/18bb31b2f24127a8.
Report an issue: GitHub.