エラーの概要

GitLabの404エラーは、指定したプロジェクト・マージリクエスト・ファイルなどのリソースが見つからないことを意味します。API呼び出しやWebUIでのアクセス時に発生し、プロジェクトの存在確認、アクセス権限、リソースパスの誤入力などが主な原因です。プロジェクト削除された、URLエンコーディングが正しくない、トークン権限が不足している場合にも表示されます。

実際のエラーメッセージ例

GitLab API経由でのレスポンス

{
  "message": "404 Not Found"
}

curlコマンドでの出力:

$ curl -H "PRIVATE-TOKEN: <your-token>" "https://gitlab.com/api/v4/projects/wrong-namespace%2Fproject-name"
{"message":"404 Not Found"}

WebUIでのブラウザ表示:

404 Not Found

The page you're looking for could not be found.

Python requests ライブラリでのエラー

import requests
response = requests.get(
    "https://gitlab.com/api/v4/projects/invalid-path",
    headers={"PRIVATE-TOKEN": "<your-token>"}
)
print(response.status_code)  # 404

よくある原因と解決手順

原因1:プロジェクトIDまたはパスの誤入力

GitLab APIプロジェクト指定時に、数字のプロジェクトID、またはURL形式の namespace/project-name を使用します。パスに特殊文字やスペースが含まれる場合は、URLエンコーディングが必須です。スラッシュ(/)は %2F にエンコードする必要があります。

Before(エラーが起きるコード):

# スラッシュがエンコードされていない
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects/my-group/my-project/repository/commits"

# 結果:404 Not Found

After(修正後):

# スラッシュをURLエンコードする(%2F)
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects/my-group%2Fmy-project/repository/commits"

# または数字のプロジェクトIDを使用
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects/12345/repository/commits"

原因2:トークンの権限不足またはプロジェクトへのアクセス権限がない

プライベートプロジェクトへのアクセスには、適切な権限を持つトークンが必要です。トークンが存在しない、有効期限が切れている、または該当プロジェクトへのアクセス権限がないメンバーが使用している場合、404が返されます。GitLabはセキュリティの観点から、権限がないリソースを404で返すため、403(Forbidden)と区別されません。

Before(エラーが起きるコード):

import requests

# 有効期限切れのトークンを使用
headers = {"PRIVATE-TOKEN": "glpat-xxxxxxxxxxxx"}
response = requests.get(
    "https://gitlab.example.com/api/v4/projects/sensitive-project",
    headers=headers
)
# 404 Not Found が返される
print(response.status_code)

After(修正後):

import requests
import os

# 環境変数から有効なトークンを取得
token = os.environ.get("GITLAB_TOKEN")
if not token:
    raise ValueError("GITLAB_TOKEN is not set")

headers = {"PRIVATE-TOKEN": token}
response = requests.get(
    "https://gitlab.example.com/api/v4/projects/sensitive-project",
    headers=headers
)

if response.status_code == 404:
    print("プロジェクトが見つからないか、アクセス権限がありません")
elif response.status_code == 200:
    print("成功")

原因3:プロジェクトが削除された、または名前空間が変更された

プロジェクト削除された場合、そのURLにアクセスすると404が返されます。また、グループやユーザーの名前空間が変更された場合、古いパスでのアクセスも404になります。プロジェクトが転送(移動)された場合、古いURLから新しいURLへのリダイレクトが設定されていないと404が表示されます。

Before(エラーが起きるコード):

# 旧いプロジェクトパスでアクセス(名前空間が変更済み)
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects/old-team%2Fproject-name"

# 404 Not Found

After(修正後):

# 新しいプロジェクトパスでアクセス
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects/new-team%2Fproject-name"

# または、プロジェクトの詳細情報を確認して実際のパスを確認
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects" | jq '.[] | select(.name=="project-name")'

原因4:マージリクエストやイシューのIDが存在しない

プロジェクト内の特定マージリクエスト、イシュー、パイプラインなどのIDが存在しない場合、404が返されます。プロジェクトIDは正しいがリソースIDが誤っている、または削除されている状況です。

Before(エラーが起きるコード):

# マージリクエストID 999 が存在しない
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects/12345/merge_requests/999"

# 404 Not Found

After(修正後):

# プロジェクト内のすべてのマージリクエストをリストして確認
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects/12345/merge_requests" | jq '.[] | {id, title}'

# 正しいIDでアクセス
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects/12345/merge_requests/42"

原因5:ファイルパスが間違っている、またはブランチが削除されている

リポジトリ内のファイルにアクセスする際、ファイルパスやブランチ名が誤っている場合に404が返されます。特定ブランチ削除されている、ファイルが移動された、パスの大文字小文字が一致していない場合も対象です。

Before(エラーが起きるコード):

# 削除済みブランチ "feature-old" からファイルを取得
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects/12345/repository/files/src%2Fmain.py?ref=feature-old"

# 404 Not Found

After(修正後):

# 存在するブランチを確認
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects/12345/repository/branches" | jq '.[] | .name'

# 正しいブランチでアクセス
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.com/api/v4/projects/12345/repository/files/src%2Fmain.py?ref=main"

ツール固有の注意点

GitLab API固有の問題:

GitLab APIではリソース所有者の権限がない場合、セキュリティ上の理由から404を返します。つまり、403(Forbidden)ではなく404が表示されるため、「リソースがない」のか「権限がない」のか区別が難しくなります。WebUIで同じプロジェクトにアクセスできるか確認することが有効です。

グループ・サブグループ間でのパス変更:

グループやサブグループの構造が変わった場合、API呼び出しのパスも対応する必要があります。/groups/<id>/groups/<path> の両形式がサポートされていますが、パスベースでアクセスする場合は完全な階層パスが必須です。

Self-hosted GitLab でのURL確認:

オンプレミスGitLab環境では、WebUIで確認したURLAPI エンドポイントのベースURLが一致しているか確認します。リバースプロキシやロードバランサー経由でアクセスしている場合、gitlab.ymlexternal_url 設定が正確か検証が必要です。

Legacy API vs GraphQL

GitLab REST APIGraphQL APIでは、リソースの指定方法が異なります。特にマージリクエストやパイプラインではプロジェクトIDが必須の場合があり、プロジェクトパスだけでは404になることがあります。

それでも解決しない場合

確認すべきログの場所:

GitLab管理者権限がある場合は、管理画面の「ログ」セクションで詳細なアクセスログを確認します。また、自身のGitLabインスタンスへのアクセス履歴は、WebUI右上のプロフィール > 「Last activity」で時系列確認できます。

デバッグコマンド:

# トークンの権限を確認
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.example.com/api/v4/user"

# プロジェクト一覧を取得(アクセス可能なもの)
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.example.com/api/v4/projects?pagination=keyset&per_page=100"

# 特定プロジェクトの詳細情報を確認
curl -H "PRIVATE-TOKEN: <your-token>" \
  "https://gitlab.example.com/api/v4/projects/<project-id>"

公式ドキュメント参照:

  • GitLab API ドキュメント:https://docs.gitlab.com/ee/api/
  • プロジェクトAPIhttps://docs.gitlab.com/ee/api/projects.html
  • トークン管理:https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html

コミュニティリソース:

GitLab公式フォーラム(https://forum.gitlab.com)やGitHub Issues(GitLab Runnerなどのオープンソースコンポーネントの場合)でも同様の問題が報告されていないか検索してみてください。特に「404」「Not Found」「API」を組み合わせたキーワード検索が有効です。


免責事項:本記事の内容は、執筆時点の公開情報をもとに作成したものです。ソフトウェアの仕様は予告なく変更されることがあります。最新の情報は各ツールの公式サポートページをご確認ください。本記事の情報を利用した結果生じたいかなる損害についても、著者および運営者は責任を負いかねます。