The GitHub Actions runner failed to find an artifact it had previously declared as uploaded, indicating a race condition or a problem with artifact indexing.

The most common culprit is a simple typo in the artifact name. GitHub Actions is case-sensitive for artifact names, so my-artifact is not the same as My-Artifact. This happens when the name in your actions/upload-artifact step doesn’t precisely match the name in your actions/download-artifact step.

Diagnosis: Check your upload-artifact and download-artifact steps in your workflow YAML.

- name: Upload coverage report
  uses: actions/upload-artifact@v3
  with:
    name: coverage-report # <-- Note this name
    path: ./coverage.xml

# ... later ...

- name: Download coverage report
  uses: actions/download-artifact@v3
  with:
    name: Coverage-Report # <-- Typo here, case mismatch
    path: ./test-results

Fix: Ensure the name parameter is identical in both upload-artifact and download-artifact steps.

- name: Upload coverage report
  uses: actions/upload-artifact@v3
  with:
    name: coverage-report
    path: ./coverage.xml

# ... later ...

- name: Download coverage report
  uses: actions/download-artifact@v3
  with:
    name: coverage-report # <-- Corrected name
    path: ./test-results

This works because the artifact is internally indexed by its exact name, and a mismatch prevents the runner from locating the stored data.

Another frequent cause is uploading an artifact with a wildcard path that doesn’t actually match any files. The upload-artifact action might report success even if the path glob resolves to zero files, leading to an empty artifact. When you later try to download it, it appears "not found" because it was never truly created with content.

Diagnosis: Run your workflow and carefully examine the output of the upload-artifact step. Look for messages indicating that the specified path matched zero files.

Run actions/upload-artifact@v3
...
No files were found that match the path: ./build/outputs/*.jar

Fix: Adjust the path glob to accurately capture the files you intend to upload. For example, if you expect .jar files, ensure the directory exists and contains them. If you’re unsure, use a more specific path or add a step to list files beforehand.

- name: List files before upload
  run: ls -R ./build/outputs/

- name: Upload JARs
  uses: actions/upload-artifact@v3
  with:
    name: my-jars
    path: ./build/outputs/*.jar # <-- Ensure this path actually has files

This works because the upload-artifact action requires at least one file to create a valid, downloadable artifact entry.

A less common, but still prevalent, issue is uploading an artifact within a job that is configured to run in parallel with other jobs that might also be trying to access or manipulate the same artifact name. While GitHub Actions tries to manage this, race conditions can occur, especially with very short-lived artifacts or complex workflows.

Diagnosis: Examine your workflow’s YAML file. Identify jobs that run in parallel and might be interacting with the same artifact name. Check for dependencies or explicit needs that could lead to concurrent access.

Fix: Introduce a unique identifier to your artifact name, such as the commit SHA or a timestamp, to ensure each upload is distinct. Alternatively, serialize access by using needs to create a strict dependency chain for artifact creation and consumption.

jobs:
  build-and-upload:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Build
        run: echo "Building..."
      - name: Upload artifact
        uses: actions/upload-artifact@v3
        with:

          name: build-output-${{ github.sha }} # <-- Unique name per commit

          path: ./build/

  download-and-test:
    runs-on: ubuntu-latest
    needs: build-and-upload
    steps:
      - name: Download artifact
        uses: actions/download-artifact@v3
        with:

          name: build-output-${{ github.sha }} # <-- Matches the unique upload name

          path: ./downloaded-build

This prevents race conditions by ensuring that each artifact upload and download operation targets a specific, non-conflicting artifact instance.

The artifact might have been uploaded using an older version of the actions/upload-artifact action that had different behavior or bugs related to artifact storage or naming.

Diagnosis: Check the version of actions/upload-artifact used in your workflow.

- name: Upload artifact
  uses: actions/upload-artifact@v2 # <-- Older version
  with:
    name: my-artifact
    path: ./dist

Fix: Upgrade to the latest stable version of actions/upload-artifact.

- name: Upload artifact
  uses: actions/upload-artifact@v3 # <-- Latest version
  with:
    name: my-artifact
    path: ./dist

This ensures you benefit from bug fixes and improved stability in the artifact handling logic.

It’s possible that the artifact was uploaded, but the job that needs to download it is running on a different runner type (e.g., macOS vs. Ubuntu) and the artifact’s content isn’t compatible or correctly packaged for that specific runner environment. While less common for simple files, it can happen with complex build outputs.

Diagnosis: Compare the runs-on declarations for the job that uploads the artifact and the job that downloads it.

jobs:
  upload_job:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/upload-artifact@v3
        with:
          name: my-data
          path: ./output/

  download_job:
    runs-on: macos-latest # <-- Different runner OS
    needs: upload_job
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: my-data
          path: ./downloaded-data

Fix: Ensure that artifact content is cross-platform compatible or use the same runner OS for both uploading and downloading jobs if possible. If cross-platform compatibility is required, consider uploading a compressed archive (.zip, .tar.gz) that is universally extractable.

jobs:
  upload_job:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/upload-artifact@v3
        with:
          name: my-data
          path: ./output/
          retention-days: 5 # Example: keep for 5 days

  download_job:
    runs-on: ubuntu-latest # <-- Same runner OS
    needs: upload_job
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: my-data
          path: ./downloaded-data

This ensures consistency in how the artifact is stored and retrieved, avoiding environment-specific interpretation issues.

Finally, a transient network issue or a temporary outage with GitHub’s artifact storage service could cause the upload to appear successful to the runner but fail to be fully persisted or indexed by the backend.

Diagnosis: Check the GitHub Status page (https://www.githubstatus.com/) for any ongoing incidents related to Actions or Artifacts. Review the runner logs for any network-related errors or timeouts during the upload phase.

Fix: If there’s a reported incident, wait for it to be resolved. If no incident is reported, retrying the workflow is the primary recourse. If the issue persists across multiple runs without any discernible pattern or specific error message, it might indicate a deeper, intermittent platform problem that requires reporting to GitHub Support.

# No specific command, rely on retries and GitHub Status

This works because transient network glitches are often resolved by simply re-attempting the operation once the underlying connectivity is restored.

The next error you’ll likely encounter is a "workflow_run" trigger not firing as expected, or a "permissions" error if your workflow tries to access something it shouldn’t.

Want structured learning?

Take the full Github-actions course →