immich-app/immich · error · ApiException

Failed to get sync stream: $errorBody

Error message

Failed to get sync stream: $errorBody

What it means

The sync-stream repository opens an HTTP request and expects status 200. Any other status aborts the stream before reading: the error body is drained and wrapped in an ApiException carrying the status code and the raw response body under the message 'Failed to get sync stream: ...'.

Solutions

  1. Log the included status code and error body to identify the server-side cause
  2. Refresh authentication (re-login / token renewal) on 401/403 before retrying
  3. Retry with backoff on 5xx / transient gateway errors
  4. Confirm the server version supports the sync-stream endpoint

Example fix

// before
final delta = await syncApi.getSyncStream(...); // throws raw ApiException
// after
try {
  await syncApi.getSyncStream(...);
} on ApiException catch (e) {
  if (e.code == 401) await reauthenticate();
  else if (e.code >= 500) scheduleRetryWithBackoff();
  rethrow;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Dart: sanity-check session before opening the stream
if (accessToken == null || serverUrl == null) {
  throw StateError('Not authenticated for sync stream');
}

Try / catch

try {
  await for (final chunk in syncApi.getSyncStream(...)) { ... }
} on ApiException catch (e) {
  if (e.code == 401 || e.code == 403) {
    await reauthenticate();
  } else if (e.code >= 500) {
    retryWithBackoff();
  }
}

Prevention

When it happens

Trigger: Server responds with non-200 (401 expired token, 403, 500, 502) to the sync-stream request; server endpoint missing or a proxy intercepts the stream request.

Common situations: Access token expired between login and sync; server upgraded/changed API so the sync endpoint errors; reverse proxy or CDN rejects long-lived streaming requests; server error while checkpointing.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15). Data as JSON: /api/errors/b3cffea2e716142f. Report an issue: GitHub.

Appendix: source

Thrown at mobile/lib/infrastructure/repositories/sync_api.repository.dart:89

    String previousChunk = '';
    final List<String> lines = [];

    bool shouldAbort = false;

    void abort() {
      _logger.warning("Abort requested, stopping sync stream");
      shouldAbort = true;
    }

    final reset = onReset ?? () {};

    try {
      final response = await client.send(request);

      if (response.statusCode != 200) {
        final errorBody = await response.stream.bytesToString();
        throw ApiException(response.statusCode, 'Failed to get sync stream: $errorBody');
      }

      await for (final chunk in response.stream.transform(utf8.decoder)) {
        if (shouldAbort) {
          break;
        }

        previousChunk += chunk;
        final parts = previousChunk.split('\n');
        previousChunk = parts.removeLast();
        lines.addAll(parts);

        if (lines.length < batchSize) {
          continue;
        }

        await onData(_parseLines(lines), abort, reset);
        lines.clear();

View on GitHub (pinned to e55ac299a4)