An artifact with this name already exists in GitHub Actions
The error an artifact with this name already exists is a 409 from the artifact service, and it has been the intended behavior of GitHub Actions since version 4 of actions/upload-artifact: a name is unique within a run, and an artifact cannot be rewritten once finalized. The second upload is not overwriting the first and is not being merged into it; it is refused.

What this error means
One leg of a matrix uploads and the rest fail, or a second upload in the same job fails while the first passed. Whichever leg got there first survives, so the failing job changes between runs and the whole thing reads as flaky. The log above the error looks healthy: a file count, a valid name, a valid root directory. The failure line does not name the artifact it collided with, a gap reported against the action itself.
Error: Failed to CreateArtifact: Received non-retryable error: Failed request: (409) Conflict: an artifact with this name already exists on the workflow runA minimal workflow that produces it
This file is written for this page and has never been run. It is the shape the version 4 migration document uses as its own example of what stopped working: three matrix legs, each uploading its own file under one shared artifact name. Under version 3 that produced one artifact holding three files. Under version 4 the first leg creates it and the other two get a 409.
name: ci
on:
push:
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- run: echo "hello from ${{ matrix.os }}" > file.txt
- uses: actions/upload-artifact@v7
with:
name: my-artifact
path: file.txtCommon causes
Every leg of a matrix uploads the same name
The dominant cause, and the one the migration document leads with. Under version 3 this was the normal way to collect output from several platforms into one artifact. Under version 4 it is a race, and which leg wins varies, which is why this is usually first reported as a flaky matrix rather than a duplicated name.
The same name is uploaded twice in one run, in different jobs
Because uniqueness is per run rather than per job, splitting the uploads apart does not separate the names. Two jobs that both upload under coverage collide exactly as if they were two steps in one job, and moving one into its own job is the most common failed fix for this error.
A shared or third-party action uploads a name you do not control
Composite and marketplace actions often upload a diagnostic bundle under a fixed name. Call one twice in a run and the second call fails inside somebody else's code. The Microsoft action cited below is exactly that: it offered no way to set the artifact name, so every workflow calling it twice broke.
overwrite is set but is looking at the wrong name
On version 7, direct upload with archive: false derives the name from the file while overwrite is reported to still delete by the name input. The delete removes nothing, the create hits the existing artifact, and you get this error despite having asked for overwriting. The practical answer is to avoid combining those two inputs.
How to fix it
Put the matrix value in the name
The corrected version of the illustrative workflow above, and the change the migration document makes in its own diff. Every leg now uploads a distinct artifact and none races any other. It is the right fix for most matrices, because the artifacts really are different.
- uses: actions/upload-artifact@v7
with:
name: my-artifact-${{ matrix.os }}
path: file.txt
if-no-files-found: errorDownload them back as one directory
Splitting the upload only moves the problem if the consumer still expects one artifact. The download side has two inputs for this: pattern selects the set by prefix and merge-multiple puts them in one directory instead of one subdirectory each. It pairs with the fix above as written.
collect:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v8
with:
path: all
pattern: my-artifact-*
merge-multiple: true
- run: ls -R allMerge into one real artifact when you need a single download
If something outside the workflow downloads the artifact, a set of names is not enough and you want one object. The merge sub-action does that in an extra job: it pulls the matching artifacts, combines them and uploads one. It costs a round trip of the data, which is why the pattern download is better when a later job is the only consumer.
merge:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/upload-artifact/merge@v7
with:
name: all-my-files
pattern: my-artifact-*Use overwrite only where last writer wins is what you mean
Republishing one artifact from one job, such as a preview build that should reflect the latest push within a run, is what this input was added for. Do not reach for it to silence a matrix: the legs delete one another and the survivor is whichever finished last. The replacement is a new artifact with a new id, so any link captured earlier goes stale.
- uses: actions/upload-artifact@v7
with:
name: preview
path: dist
overwrite: true
if-no-files-found: errorWhat version 4 changed, and when each replacement arrived
Version 4 landed on 14 December 2023 as a rewrite of the artifact backend. Its release notes call it a major update with breaking changes, adding that artifacts created with version 3 and below are not compatible and that uploads and downloads must use the same major versions. Immutability is the piece that produces this error: the migration document says that in version 4 artifacts are immutable unless deleted.
The replacements did not all arrive at once, which is worth knowing if you are reading advice from early 2024 and wondering why an input does not exist. The dates below come from the release notes, checked today against the GitHub releases API.
Everything after version 4.4.0 is runtime and packaging rather than behavior. Version 5 added Node 24 support, version 6 made Node 24 the default and raised the minimum Actions runner to 2.327.1, and version 7 added direct uploads and moved to ESM. None of them changed how names collide.
| Version | Released | What it changed about names |
|---|---|---|
| v4.0.0 | 14 December 2023 | Artifacts became immutable and names unique within a run |
| v4.2.0 | 18 January 2024 | Added overwrite, which deletes the old artifact first |
| v4.3.0 | 23 January 2024 | Added the merge sub-action for combining artifacts |
| v4.4.0 | 30 August 2024 | Excluded hidden files by default, unrelated to naming |
Unique per run, not per job
The obvious reading of the message is that the collision is within a job, and it is not. The reporter of one widely linked case tested exactly that, splitting each upload into its own job, and reported back that it made no difference: the name has to be unique across the whole run. That is why moving a duplicated upload into a separate job does not help.
Two inputs sit either side of the rule. overwrite: true deletes any artifact with that name before uploading, which gives last-writer-wins, and the migration document adds the consequence that matters: this creates an entirely new artifact with a different id from the previous one. Set it on a matrix and the legs delete each other in whatever order they finish.
The other direction is the merge sub-action, which downloads a set of artifacts and re-uploads them as one, at the cost of an extra job and a round trip of the data. One open edge on version 7: with archive: false the name comes from the uploaded file rather than the name input, and a report says overwrite still deletes by name.
Why there is no recorded run on this page
A 409 here is a correct answer to a request for something the service does not allow. It is deterministic and documented as intended, and re-running produces it again in whichever leg loses the race. Nothing in it is transient and there is nothing for a runner to repair: the fix is a different name, and that lives in the workflow file.
How to prevent it
- Derive every artifact name from the thing that makes it unique, usually the matrix value.
- Treat artifact names as unique across the run, not the job, when reviewing a workflow.
- Give any shared or composite action that uploads an artifact a name input.
- Reserve
overwritefor a single deliberate republish and never for a matrix.
Frequently asked questions
Why does upload-artifact say a name already exists in a matrix?
Are GitHub Actions artifact names unique per job or per run?
What does overwrite: true do in actions/upload-artifact?
How do I combine matrix artifacts into one artifact now?
merge sub-action with a pattern matching them. It downloads the set, combines it and uploads one artifact under your name. If the only consumer is a later job in the same run, download by pattern with merge-multiple instead.