Skip to content

FILE_MIGRATE_ errors not handled for file downloads (or: why custom contact photos don't work) #3604

@TKIPisalegacycipher

Description

@TKIPisalegacycipher

FILE_MIGRATE_ errors not handled for file downloads

Problem

Downloading ChatPhotoInfo.Small files for personal photos (photos set by the current user for a contact) permanently fails with FILE_MIGRATE_1 (HTTP 303). The photo is stored on DC 1 but TDLib tries to download from DC 3 and never retries on the correct DC.

Root Cause

NetQueryDispatcher::try_fix_migrate() (td/telegram/net/NetQueryDispatcher.cpp:390-406) handles 303 errors, but only for three prefixes:

static constexpr CSlice prefixes[] = {"PHONE_MIGRATE_", "NETWORK_MIGRATE_", "USER_MIGRATE_"};

FILE_MIGRATE_ is not in this list. So when a file download query returns 303 / FILE_MIGRATE_1:

  1. NetQueryDispatcher::dispatch() (line 96-97) sees code 303, calls try_fix_migrate()
  2. try_fix_migrate() doesn't match FILE_MIGRATE_, does nothing, returns
  3. The error propagates to FileManager::on_download_error_impl() (line 4913)
  4. on_download_error_impl() has no handler for it either (lines 4918-4961 handle FILE_ID_INVALID, file reference errors, FILE_DOWNLOAD_RESTART, MTPROTO_CLUSTER_INVALID — but not FILE_MIGRATE)
  5. The error is logged at line 4972 and converted to a 400 error at line 4988
  6. on_file_load_error() (line 4991) cancels the download permanently

Reproduction

  1. Set a personal photo for a contact (via "Set Photo for This Contact")
  2. The ChatPhotoInfo.Small file for that contact will have a DC ID that may differ from the DC where the file is actually stored
  3. TDLib will attempt to download from the stored DC, receive FILE_MIGRATE_N, and fail permanently
  4. The contact's profile picture will only ever show the blurry minithumbnail

Evidence from logs

[Session:3:download_small#0] Receive error [...] [Error : 303 : FILE_MIGRATE_1]
Failed to Download file 4385(0) of type ChatPhoto: [Error : 303 : FILE_MIGRATE_1]
Failed to Download file 4377(0) of type ChatPhoto: [Error : 303 : FILE_MIGRATE_1]

Key files and lines

  • td/telegram/net/NetQueryDispatcher.cpp lines 390-406: try_fix_migrate() — missing FILE_MIGRATE_ prefix
  • td/telegram/net/NetQueryDispatcher.cpp lines 96-97: 303 error dispatch calls try_fix_migrate()
  • td/telegram/files/FileManager.cpp lines 4918-4961: on_download_error_impl() — no FILE_MIGRATE handler
  • td/telegram/files/FileManager.cpp lines 4972-4973: Error logged as warning, then treated as fatal

Possible fix

Add FILE_MIGRATE_ handling in try_fix_migrate(), but without changing the main DC (unlike the other migrate errors, this just means resend the query to a different DC):

// In try_fix_migrate(), before the existing prefix loop:
static constexpr CSlice file_migrate_prefix = "FILE_MIGRATE_";
if (begins_with(error_message, file_migrate_prefix)) {
    auto new_dc_id = to_integer<int32>(error_message.substr(file_migrate_prefix.size()));
    if (DcId::is_valid(new_dc_id)) {
        net_query->resend(DcId::internal(new_dc_id));
    }
    return;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions