#2000·postiz-app

Instagram: "Timeout downloading media" (Meta 2207003) doesn't say which media failed, or that Meta is the one fetching

Author: boydthomsonCreated Sep 1, 2026Updated Sep 17, 2026

Description

When Meta returns error code 2207003, Postiz surfaces it to the user as:

Timeout downloading media, please try again

That string is mapped at libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts:159-162. It is close to unactionable, and for self-hosters it is actively misleading. Four separate problems:

1. It doesn't say which media failed. Container creation runs inside Promise.all(firstPost.media.map(...)) (instagram.provider.ts:~659). When one item rejects, Promise.all rejects immediately and the only trace of which item is an at async Promise.all (index 4) line buried in the raw stack inside the Post.error JSON column. The index is never mapped back to a filename or URL, and it is not shown in the UI at all. On an 8-image carousel the user is told "media" failed with no way to know which one.

2. It doesn't say who timed out. The phrasing reads as though Postiz failed to read its own storage. The natural user reaction is "but all my media is in Postiz". In reality Postiz sends Meta a URL and Meta's servers fetch it from the user's public Postiz instance — so the timeout is Meta's, pulling data out of your deployment. Nothing in the message conveys that, and it sends people looking in entirely the wrong place.

3. "Please try again" is wrong for this failure mode. For large media on a constrained uplink this is deterministic, not transient. Retrying reproduces it exactly. The message advises the one thing guaranteed not to work.

4. No diagnostic context is captured. Media size, elapsed time and bytes transferred are all available at the point of failure but none are recorded, so there is nothing to correlate against and no way to tell 2207003 (slow) apart from 2207052 (unreachable) without a reverse-proxy log.

Related but distinct: #1472 and #1004 both cover "Media fetch failed" (9004 / 2207052), where Meta cannot fetch the URL at all. This is code 2207003, where Meta reaches the URL fine and the transfer is then cut short. Same user-facing dead end, different cause.

Reproduction steps

  1. Self-host Postiz with STORAGE_PROVIDER=local behind a public HTTPS reverse proxy, on a connection with a modest upload speed (mine measures ~2.5 MB/s / ~20 Mbit).
  2. Upload 8 full-resolution phone photos via POST /api/public/v1/upload — roughly 4–6 MB each, ~34 MB total.
  3. Create an Instagram carousel post using all 8 and publish.
  4. Publishing fails. Post.state becomes ERROR and the UI shows only "Timeout downloading media, please try again".

Expected behavior

An error a self-hoster can act on. Something like:

Instagram timed out downloading photo-04.jpg (image 4 of 8, 5.1 MB) from https://<your-postiz>/uploads/2026/08/30/c8ee….jpg. Instagram downloads media from your Postiz instance rather than receiving an upload. Meta fetches carousel items in parallel, so a large carousel on a slow upload link can exceed their fetch timeout. Consider reducing image file sizes — Instagram renders feed images at 1080px wide.

Concretely, four changes:

  • Surface the failing item's filename, carousel index and file size in the user-facing error, not just in a stack trace inside a JSON column.
  • Reword so it is unambiguous that Meta is fetching from the user's instance.
  • Swap Promise.all for Promise.allSettled so every failing item is reported in one pass instead of only the first to reject.
  • Log bytes served and elapsed time for each media fetch, so 2207003 can be distinguished from 2207052 without reading reverse-proxy logs.

A pre-flight warning at post time when a carousel's total payload is large (or optional server-side downscaling on upload) would prevent the failure altogether, since Instagram re-compresses to 1080px regardless.

Actual Behavior with Screenshots

UI and Post.error show only:

Timeout downloading media, please try again

Decoded from the Post.error column:

ApplicationFailure: Timeout downloading media, please try again
    at InstagramProvider.fetch (/app/libraries/nestjs-libraries/src/integrations/social.abstract.ts:455:11)
    at processTicksAndRejections (node:internal/process/task_queues:105:5)
    at /app/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts:725:11
    at async Promise.all (index 4)
    at InstagramProvider.postPending (/app/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts:659:20)
    at PostActivity.postSocialInternal (/app/apps/orchestrator/src/activities/post.activity.ts:268:11)
  type: 'bad_body'

index 4 is the only clue to which image failed, and it is not shown anywhere in the UI.

What was actually happening. I only found the cause by reading the reverse-proxy access log. Meta was reaching the server and getting 200s — but the byte counts served were short, and short by a different amount on each attempt:

time                  file         bytes served   actual size
31/Aug 18:12:09       e8f9cfd1…     4,733,105  /  4,733,105   complete
31/Aug 18:12:10       36a6d571…     4,685,357  /  4,866,133   CUT
31/Aug 18:12:10       c8eeee6c…     4,750,893  /  5,398,334   CUT
31/Aug 18:12:10       eecc1e30…     4,521,517  /  6,270,719   CUT
31/Aug 18:12:10       3859dfe1…     3,489,325  /  5,542,203   CUT
01/Sep 00:53:26       eecc1e30…     3,276,333  /  6,270,719   CUT (different offset)

Note the timestamps: facebookexternalhit requests four items within the same second. Meta fetches carousel media in parallel, so on a ~2.5 MB/s uplink each concurrent stream gets roughly 600 KB/s and a 6 MB image needs ~10s on its own — past Meta's fetch timeout. Files under ~2.5 MB completed every time; files over ~4.5 MB were cut every time, at varying offsets. That varying offset is what identifies it as a timeout rather than a size limit.

Resizing the images to 1440px long edge (56.4 MB → 5.9 MB across the library) fixed it completely. No Postiz configuration was wrong at any point — but nothing in the error pointed anywhere near the actual problem.

Operating system

Linux (Debian, Docker Compose, STORAGE_PROVIDER=local, nginx reverse proxy)

Node Version

Bundled container image

Provide any additional context for the Bug.

  • Postiz v2.23.0 (NEXT_PUBLIC_VERSION), self-hosted via Docker Compose
  • STORAGE_PROVIDER=local, UPLOAD_DIRECTORY=/uploads
  • Public HTTPS via nginx reverse proxy, valid certificate; media URLs verified publicly reachable and returning 200 image/jpeg from outside the network
  • Facebook/Instagram fetch user-agent observed in proxy logs as facebookexternalhit/1.1 from 69.171.234.x and 173.252.x.x
  • Error code reference: Meta 2207003 — mapped in instagram.provider.ts:159