Instagram's media_publish endpoint can return a generic code 1 or code 2 error for a post that went live. In our production traffic in August and September 2026, a Reel and a Story were published while the call reported failure. Meta's pages for media_publish and for Instagram error codes do not document this (checked 18 October 2026), so treat that error as an unknown outcome and read the container before you retry.
The follow-up call is the trap. The container keeps reading status_code: FINISHED, never PUBLISHED, and a second media_publish on it returns code 24, subcode 2207006. Meta documents that pair as "The media with {media-id} cannot be found" and advises "Generate a new container and use it to try again" (error codes reference, checked 18 October 2026). If the post is already live, following that advice publishes it twice.
What does Meta document for media_publish errors?
Meta documents none of the failure above. The media_publish reference takes creation_id (the container ID) and returns the Instagram media ID on success. It has no section on retries, duplicates, container status after publishing, or container reuse (checked 18 October 2026).
The content publishing guide defines the five container statuses and recommends polling "about once a minute, for up to five minutes". It gives no guidance for a media_publish call that fails after a container exists (checked 18 October 2026). The error codes reference has no row for code 2, and its only row for code 1 is subcode 2207057, a thumbnail offset error. A generic code 1 or 2 from media_publish is an undocumented response.
| `status_code` | Meta's definition (checked 18 October 2026) |
|---|---|
IN_PROGRESS | The container is still in the publishing process. |
FINISHED | The container and its media object are ready to be published. |
PUBLISHED | The container's media object has been published. |
ERROR | The container failed to complete the publishing process. |
EXPIRED | The container was not published within 24 hours and has expired. |
Read the PUBLISHED row as a promise. In every case we observed, a container whose post was live still read FINISHED. So status_code cannot be your proof that a publish worked, and it cannot be your proof that one failed.
What does Instagram error 2207006 mean on media_publish?
Meta documents error code 24 / subcode 2207006 as a missing-media problem, and on a container that still reads FINISHED after an earlier attempt it meant the post was already published. These are first-party observations of Instagram's behaviour, not Meta documentation, and they cover August and September 2026 only.
In August 2026, a Reel went live while media_publish answered code 2. The caller saw a failure and nothing in the response carried a media ID. In September 2026, the first media_publish for a Story answered code 2 after about the latency of a successful publish. The container kept reading FINISHED, and every further media_publish on it, repeated over several minutes, answered code 24 / subcode 2207006. Re-publishing never produced a second post and never returned a media ID.
Across the container status reads we collected, PUBLISHED was never returned. We make no claim about every account, publish type, or login flow. The pattern held on both the Instagram Login and the Facebook Login paths in the cases we looked at.
The payload below is an example with placeholder values, reconstructed in the standard Graph error envelope. It is not a captured response. The error_user_msg text depends on the account's locale. Match on code plus error_subcode, never on the message text, and read the container status alongside it.
What does each media_publish response mean, and what should you do?
The table maps each response and container status_code to what happened and the safe next step. Rows marked "observed" come from our August and September 2026 traffic. Rows quoting Meta come from the error codes reference, checked 18 October 2026.
| `media_publish` returned | Container `status_code` | What actually happened | What to do |
|---|---|---|---|
200 with {"id": "..."} | any | Published. The ID is the media ID. | Store the ID. Do not expect a later status read to say PUBLISHED. |
| Code 1 or 2, "unknown error" | FINISHED | Unknown. In August and September 2026 this included posts that were live. | Do not create a new container. Re-publish the same container once, then verify. |
| Code 1 or 2 | ERROR | Not published. The status response was {"status_code":"ERROR","status":"ERROR"} and gave no reason. | Create a new container. |
| Code 1 or 2 | EXPIRED | Not published. The 24-hour window passed. | Create a new container. |
| Code 1 or 2 | IN_PROGRESS | Not published yet. | Keep polling the container, at most once a minute. |
| Code 24 / 2207006 | FINISHED | Observed in every case: already published by an earlier call. Meta's reading: media not found, or a permission or expired-token problem. | Treat as published after the token check. Do not create a new container. |
| Code 24 / 2207006 | ERROR, EXPIRED, or the status read fails | Meta's reading applies: missing media or a token problem. | Follow Meta: check the token, then create a new container. |
| Code 9007 / 2207027 | FINISHED | Meta has not finished preparing the media. | Wait and call media_publish again, as Meta advises. |
| Code 24 / 2207008 | any | Meta: temporary error, "try again 1-2 times in the next 30 seconds to 2 minutes". | Same container, bounded retries, then check status before anything else. |
| Code 9 / 2207042 | FINISHED | Daily publish cap reached. Nothing was published. | Wait for the window. See the 100-posts limit post. |
The two FINISHED rows carry the risk. The same container status sits under an error that means "go ahead and retry" and an error that means "it is already done", and the response body is the only thing that tells them apart.
Should you retry media_publish after an error?
Retry the same container once, never a new one. A container is a handle on one post, and creating a second container is the only step that can create a second post, so every retry before that step is cheap.
Swipe sideways to see the whole diagram
Branch on the container's status_code, retry the same container once, and create a new container only when nothing is live.
- 1.Create the container and wait for
FINISHED. - 2.Call
media_publish. A 200 with an ID is done. - 3.On any other error, save the container ID, then read
GET /{container-id}?fields=status_code. A failed read means the token or the container is the problem: stop and follow Meta's advice for that error. - 4.If the status is
ERRORorEXPIRED, nothing is live. Create a new container. - 5.If the status is
IN_PROGRESS, poll again. If it isFINISHED, callmedia_publishon the same container once more. - 6.If that call returns 24 / 2207006, your token read in step 3 succeeded, and the status is still
FINISHED, treat the post as live and verify. If it returns code 1 or 2 again, verify too. Looping adds nothing. - 7.Verify with
GET /{ig-user-id}/media: look for a post matching the caption and the time of your attempt. Only if it is absent, create a new container.
Step 7 has limits. The media listing reference returns only id by default, documents no field that links a media object back to its container, and says Story media is not supported (checked 18 October 2026). For feed posts and Reels you match on content and time, which is a heuristic.
For Stories there is no documented way to list the result, so after an ambiguous Story publish you cannot prove it failed. Treat 2207006 on a FINISHED Story container as published: a duplicate Story is a cost you can see, and a missing one is not. The step 6 reading is our inference, not a Meta statement.
A second signal is GET /{ig-user-id}/content_publishing_limit, whose quota_usage counts publishes in the last 24 hours (reference, checked via our 100-posts post on 11 September 2026). Read it before the first attempt and again after an ambiguous result. We have not tested whether a publish that returned code 2 increments it, so use it as corroboration, not proof.
Why does this break schedulers?
A scheduler that marks a post failed on the first code 2 and offers a "retry" button will, on a live post, create the container again and publish a duplicate. A scheduler that retries automatically does it without asking. The post is public on a brand's account either way, and the only cleanup is a delete. The cap makes it worse: a duplicate spends one of the account's publish slots for the window.
The failure also hides in logs. The first error looks transient, the follow-up error looks like a permissions problem (Meta's own advice says so), and nothing in either response says "this post exists". Store the container ID with every attempt. It is the only handle that lets you ask the question later. Teams that would rather not maintain this logic can start from the Instagram platform page.
Questions developers ask about media_publish errors
- Why does Instagram media_publish return an error but the post is live?
- Instagram can accept and publish the post but still answer
media_publishwith a generic code 1 or code 2 error. We saw this for a Reel in August 2026 and a Story in September 2026. Meta does not document code 2 for this endpoint (checked 18 October 2026), so read the container'sstatus_codeand check recent media before you retry. - What does Instagram error 2207006 mean?
- Meta documents error code 24 / subcode 2207006 as "The media with {media-id} cannot be found", with the advice "Generate a new container and use it to try again" (checked 18 October 2026). On a container that still read
FINISHEDafter an earliermedia_publishattempt, it meant the post was already published in every case we saw. Check your token first, then verify before you generate a new container. - Should I retry media_publish after an error?
- Retry the same container once, and only if
status_codereadsFINISHED. Never create a new container before you have checked recent media, because a new container is what creates a duplicate. Ifstatus_codeisERRORorEXPIRED, nothing was published and a new container is safe. - Why does the container status stay FINISHED?
- Meta defines
PUBLISHEDas the container's media object having been published (checked 18 October 2026), but in our August and September 2026 observations a container whose post was live still readFINISHED. We never sawPUBLISHEDreturned. Do not wait for it, and do not useFINISHEDas proof that nothing went out. - Can I call media_publish twice on the same container?
- Meta does not document what happens. In our observations, a second call after a live post returned code 24 / subcode 2207006 and never created a second post. Creating a new container is the step that creates a duplicate.
Meta claims come from Meta's developer documentation, checked 18 October 2026 unless noted. Observations of August and September 2026 are first-party and are not Meta documentation. Meta, IG User media_publish reference, Meta, Instagram Platform content publishing guide, Meta, Instagram Platform error codes reference, Meta, IG User media reference, Meta, IG User content_publishing_limit reference (checked 11 September 2026)