NG04002: Cannot match any routes. URL Segment: '…' は、移動しようとした URL に合うルートが、ルート定義(Routes)のどこにも無いときのエラーです。 URL Segment: の後ろが、ルーターが合わせられなかった部分です。その文字列と、ルート定義の path を見比べると、原因がほぼ分かります。

ERROR RuntimeError: NG04002: Cannot match any routes. URL Segment: 'user'
    at Recognizer.noMatchError (chunk-….js)

v22.2.2 で原因を1つずつ再現した結果です。

原因 開いた URL・操作 出たエラー(URL Segment) 直し方
パスの書き間違い /user(定義は users) 'user' path かリンクの文字を合わせる
大文字・小文字の違い /Users 'Users' パスは大文字・小文字を区別する
routerLink の相対パス /users で routerLink="detail/1" 'users/detail/1' / から書く、か相対の基準を直す
navigate の配列 navigate(['detail', 1]) 'detail/1' relativeTo を付ける、か / から書く
遅延ロードの子の書き間違い /admin/lists 'admin/lists' 子の Routes の path を合わせる
pathMatch: 'full' に子がある /shop/item 'shop/item' 子を持つルートから pathMatch: 'full' を外す
名前付き outlet のルートを直接開く /menu(outlet: 'side') 'menu' /home(side:menu) の形で開く
URL に丸かっこ /users/(1) 'users' ( ) を %28 %29 にする
ワイルドカード(**)が無い どれにも合わない URL 上のどれか 最後に { path: '**', … } を置く

ワイルドカードの順番・path の先頭の /・pathMatch の付け忘れは、NG04002 とは別の形で出ました(後述)。本番サーバーでリロードすると 404 になるのは、ルーターが動く前の、サーバー側の別問題です(これも後述)。

確認環境:Angular 22.2.2(@angular/core・@angular/router・@angular/cli)、TypeScript 6.0.3、Node.js 24.21.0(Linux)。原因ごとにルート定義を用意して、開発ビルド(ng build --configuration development)と本番ビルド(ng build)を作り、Chromium(Playwright 1.56.1)で URL を開いてコンソールの出力と表示を記録しました。サーバー側の 404 は、index.html に戻さない静的サーバー(Python の http.server)と、戻すサーバーを curl で比べました。仕様の説明は angular.dev のドキュメントで確かめました(確認日 2026年10月13日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「NG04002 Cannot match any routesの直し方|原因一覧」

再現に使ったルート定義

以下の表の結果は、このルート定義で確かめました。

// app.routes.ts
import { Routes } from '@angular/router';

export const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', component: Home },
  { path: 'users', component: Users },
  { path: 'users/:id', component: UserDetail },
  { path: 'shop', component: Shop, pathMatch: 'full', children: [{ path: 'item', component: Item }] },
  { path: 'admin', loadChildren: () => import('./admin.routes').then(m => m.adminRoutes) },
  { path: 'menu', component: Menu, outlet: 'side' },
];
// admin.routes.ts(遅延ロードする子のルート)
export const adminRoutes: Routes = [
  { path: 'list', component: AdminList },
];
// app.ts
@Component({
  selector: 'app-root',
  imports: [RouterOutlet],
  template: `<router-outlet /><aside><router-outlet name="side" /></aside>`,
})
export class App {}

provideRouter の基本は、関連記事「Angularルーティング設定|provideRouter・パラメータ・404」で扱っています。

エラー文:開発ビルドと本番ビルドの違い

同じ /user を開いたときの、コンソールの出力です。

開発ビルド(ng build --configuration development / ng serve)
ERROR RuntimeError: NG04002: Cannot match any routes. URL Segment: 'user'
    at Recognizer.noMatchError (http://localhost:4472/chunk-34CJH2OV.js:35079:12)

本番ビルド(ng build)
ERROR y: NG04002: 'user'
    at id.noMatchError (http://localhost:4473/chunk-PETYUQOW.js:4:181006)

本番ビルドでは「Cannot match any routes. URL Segment:」の文が消え、NG04002: 'user' だけになりました。 クラス名も短い名前(y・id)に変わります。本番のログ監視で NG04002 を探すときは、番号で探します。

どちらも、最初の表示(アドレスバーに直接入れた URL)で起きたときは、画面に何も出ず、アドレスバーは / になりました。画面内のリンクから移動したときは、前の画面のまま URL も変わりませんでした。

原因別の直し方

1. パスの書き間違い・大文字小文字

/user   → NG04002: Cannot match any routes. URL Segment: 'user'
/Users  → NG04002: Cannot match any routes. URL Segment: 'Users'
/users/ → エラーなし(/users に合った)

ルートの path は大文字・小文字を区別しました。末尾の / は、エラーにならず /users として表示されました。打ち間違いを防ぐには、パスを定数にしておき、ルート定義とリンクの両方で使う方法があります。

export const PATHS = { users: 'users', home: 'home' } as const;

{ path: PATHS.users, component: Users }
<a [routerLink]="['/', PATHS.users]">ユーザー</a>

2. routerLink の相対パス

/users の画面に、次のリンクを置いて押しました。

<a routerLink="detail/1">相対(detail/1)</a>   <!-- → /users/detail/1:NG04002 -->
<a routerLink="1">相対(1)</a>                <!-- → /users/1:表示された -->
<a routerLink="/users/1">絶対(/users/1)</a>  <!-- → /users/1:表示された -->
ERROR RuntimeError: NG04002: Cannot match any routes. URL Segment: 'users/detail/1'

routerLink は、/ で始めないと、今いるルートの下を探します。 angular.dev の RouterLink の説明では、次のように決まっています。

書き方 どこから探すか
/users/1(/ で始まる) アプリの一番上(ルート)から
1・./1(/ で始まらない) 今いるルートの子
../users/1 1つ上の階層から

URL Segment に、意図しない親のパス(ここでは users/)が付いていたら、相対パスが原因です。

3. Router.navigate は既定で一番上から

this.router.navigate(['detail', 1]);                                   // → /detail/1:NG04002
this.router.navigate(['1'], { relativeTo: this.route });               // → /users/1:表示された
ERROR RuntimeError: NG04002: Cannot match any routes. URL Segment: 'detail/1'

routerLink と逆で、navigate() は relativeTo を付けない限り、一番上から探しました。 テンプレートの routerLink="1" を、そのまま navigate(['1']) に書き換えると、行き先が変わります。

4. 遅延ロード(loadChildren)の子のルート

/admin/list   → 表示された
/admin/lists  → NG04002: Cannot match any routes. URL Segment: 'admin/lists'
/admin        → エラーなし。画面には何も表示されない

遅延ロードの子の path が合わないときも、URL Segment には親を含めた 'admin/lists' が出ました。親の loadChildren の書き方ではなく、読み込まれる側の Routes を見ます。

/admin は、子に path: '' が無いのにエラーになりませんでした。何も表示されないので、気づきにくい形です。/admin で一覧を出すなら、子に { path: '', redirectTo: 'list', pathMatch: 'full' } か { path: '', component: … } を足します。遅延ロードの書き方は、関連記事「Angular遅延ロード|loadComponentとloadChildren」で扱っています。

5. pathMatch: 'full' と子のルート

{ path: 'shop', component: Shop, pathMatch: 'full', children: [{ path: 'item', component: Item }] },
/shop       → 表示された
/shop/item  → NG04002: Cannot match any routes. URL Segment: 'shop/item'

pathMatch: 'full' は「URL の残り全部が path と同じときだけ合う」という意味です。/shop/item は shop と全部は同じではないので、子を見る前に外れました。

pathMatch 合う条件 主な使いどころ
'prefix'(既定) URL の先頭が path と同じ 子を持つルート
'full' URL の残り全部が path と同じ path: '' のリダイレクト

angular.dev のリダイレクトの説明では、path: '' のリダイレクトで pathMatch: 'full' を付けないと、すべての URL がリダイレクトされる、と注意されています。v22.2.2 の開発ビルドでは、付け忘れると起動時に次のエラーで止まりました(後述)。

6. 名前付き outlet

{ path: 'menu', component: Menu, outlet: 'side' },
/menu             → NG04002: Cannot match any routes. URL Segment: 'menu'
/home(side:menu)  → 表示された(home と menu の両方)

outlet: 'side' のルートは、<router-outlet name="side" /> 用で、通常の URL のパスからは選ばれません。URL では (side:menu) の形で書きます。リンクなら [routerLink]="[{ outlets: { side: ['menu'] } }]" です。

7. URL に丸かっこがある

Angular の URL の書き方では、( ) は名前付き outlet の区切りです。そのため、パスの中に丸かっこが入ると、思わぬ解釈になりました。

/users/(1)        → NG04002: Cannot match any routes. URL Segment: 'users'
/users/%281%29    → 表示された(users/:id の id が "(1)")
/home(foo)        → エラーなし。/home になった

ID や検索語に丸かっこが入りうるときは、リンクを作る側で encodeURIComponent() をかけるか、routerLink の配列(['/users', id])で渡します。Angular の GitHub の Issue #50787 でも、URL の丸かっこで NG04002 が出る報告があります。

NG04002 にならない設定ミス

path の先頭に / を書いた

{ path: '/about', component: About }
開発ビルド
ERROR RuntimeError: NG04014: Invalid configuration of route '/about': path cannot start with a slash
(アプリの起動そのものが失敗し、画面は空のまま)

本番ビルド
エラーなし。/home は表示された(/about のルートは使えない)

path: '' のリダイレクトに pathMatch が無い

{ path: '', redirectTo: 'home' }
開発ビルド
ERROR RuntimeError: NG04014: Invalid configuration of route '{path: "", redirectTo: "home"}': please provide 'pathMatch'. The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.

本番ビルド
エラーなし

ルート定義の形のチェック(NG04014)は、開発ビルドだけで動きました。 本番ビルドでは何も出ないので、ng serve で一度は起動して確かめます。

ワイルドカードを先頭に置いた

export const routes: Routes = [
  { path: '**', component: NotFound },   // ← 先頭
  { path: 'home', component: Home },
];
/home → 404 の画面が表示された(エラーは出ない)

ルーターは配列の上から順に探し、最初に合ったルートを使います。** はどの URL にも合うので、必ず配列の最後に置きます。loadChildren で読み込む子の Routes にも ** を書いた場合は、その子の中で最後に置きます。

404 ページの作り方

NG04002 を出さず、「ページが見つかりません」を表示するには、最後にワイルドカードのルートを置きます。

// not-found.ts
import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';

@Component({
  selector: 'app-not-found',
  imports: [RouterLink],
  template: `
    <h2>404 ページが見つかりません</h2>
    <p><a routerLink="/">トップへ戻る</a></p>`,
})
export class NotFound {}
// app.routes.ts
export const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', component: Home },
  { path: 'users', component: Users },
  { path: 'users/:id', component: UserDetail },
  { path: '**', component: NotFound, title: 'ページが見つかりません' },   // ← 最後
];
/user → 表示: 404 ページが見つかりません(URL は /user のまま。エラーなし)
/home → 表示: home
やり方 URL 向いている場面
{ path: '**', component: NotFound } 打った URL のまま 打ち間違いが分かるようにしたい
{ path: '**', redirectTo: '' } トップに変わる 404 画面を作らない小さなアプリ
{ path: '**', redirectTo: '/404' } + /404 のルート /404 に変わる アクセス解析で 404 を数えたい

ワイルドカードを置くと、NG04002 はもう出ません。開発中に原因を探すときは、次の withDebugTracing を使うか、一時的にワイルドカードを外すと、どの URL で外れたかが分かります。ID が存在しないとき(/users/999)の 404 は、ルートには合っているので、ワイルドカードでは出ません。リゾルバーやガードで判定して 404 の画面に移します(関連記事「Angularガードの使い方|CanActivateFnでログインリダイレクト」で扱っています)。

withDebugTracing で確かめる

withDebugTracing() を provideRouter に足すと、ルーターの内部のイベントがすべてコンソールに出ます。angular.dev では「ルーターのイベントの順番を調べるデバッグ用」と説明されています。

// app.config.ts
import { provideRouter, withDebugTracing } from '@angular/router';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes, withDebugTracing()),   // 調べ終わったら外す
  ],
};

/user を開いたときの出力です(開発ビルド)。

Router Event: NavigationStart
  NavigationStart(id: 1, url: '/user')
Router Event: NavigationError
  NavigationError(id: 1, url: '/user', error: Error: NG04002: Cannot match any routes. URL Segment: 'user')
ERROR RuntimeError: NG04002: Cannot match any routes. URL Segment: 'user'

NavigationStart の url が、ルーターが実際に受け取った URL です。 routerLink の相対パスが原因のときは、ここに意図しないパス(/users/detail/1 など)が出ます。合ったときは、RoutesRecognized に、どのルートに合ったかの木構造が出ます。/home を開いたときは次の行が出ました。

Router Event: RoutesRecognized
  RoutesRecognized(id: 1, url: '/home', urlAfterRedirects: '/home', state: Route(url:'', path:'') { Route(url:'home', path:'home') } )

本番ビルドでは、withDebugTracing() を付けても Router Event: の出力はありませんでした。開発ビルドで確かめます。

リロードすると 404 になる:サーバーの設定

ng serve では動くのに、本番サーバーに置いて /users でリロードすると 404 になる場合、これは NG04002 ではありません。ブラウザーがサーバーに /users というファイルを取りに行き、サーバーが「無い」と返している状態です。Angular はまだ読み込まれていません。

index.html に戻さない静的サーバーと、戻すサーバーで比べた結果です。

python3 -m http.server      /users -> 404   / -> 200
index.html に戻すサーバー   /users -> 200
見分け方 NG04002 サーバーの 404
画面 Angular のアプリ(ヘッダーなど)は出る サーバーのエラーページ
コンソール NG04002 が出る Angular のログは何も出ない
ネットワーク index.html は 200 開いた URL が 404
直す場所 ルート定義・リンク サーバーの設定

angular.dev のデプロイの説明では、ルーターを使うアプリは、無いパスへのリクエストに index.html を返すようサーバーを設定する、と書かれています(SPA モード・fallback と呼ばれる設定)。代表的な書き方です。

# nginx
location / {
  try_files $uri $uri/ /index.html;
}
# Apache(.htaccess)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ /index.html [L]
// Firebase Hosting(firebase.json)
{
  "hosting": {
    "public": "dist/app/browser",
    "rewrites": [{ "source": "**", "destination": "/index.html" }]
  }
}

サーバーの設定を変えられないときは、provideRouter(routes, withHashLocation()) で /#/users の形の URL にする方法もあります。# の後ろはサーバーに送られないので、リロードしても index.html が返ります。

原因を探す順番

順番 見るもの 分かること
1 エラーの URL Segment 合わなかった URL。親のパスが付いていたら相対パス
2 ルート定義の path 書き間違い・大文字小文字・pathMatch: 'full'
3 遅延ロードの子の Routes 子の path・path: '' の有無
4 withDebugTracing() の NavigationStart 実際に移動しようとした URL
5 ネットワークタブ サーバーの 404 か、Angular のエラーか

よくある質問

Q. ログイン後のコールバック(/callback?code=…)で NG04002 が出ます。 A. コールバック用の URL に合うルートが無いと、このエラーになります。{ path: 'callback', component: Callback } のように、受け取る画面のルートを用意します。クエリパラメータ(? の後ろ)はルートの照合に使われないので、path には書きません。

Q. ワイルドカードを置いたのに、まだ NG04002 が出ます。 A. 名前付き outlet の側で合わないときは、ワイルドカードでは受け止められませんでした。最後に { path: '**', component: NotFound } を置いた状態で /home(side:xyz) を開くと、NG04002: Cannot match any routes. URL Segment: 'xyz' が出ました。** は通常の outlet(primary)のルートだからです。URL Segment に出た部分が、どの階層の Routes で探されたかを確かめます。

Q. テスト(Vitest など)で NG04002 が出ます。 A. テスト用の provideRouter([]) に、テストで移動するルートが入っていない場合に出ます。テストで使うルートを provideRouter に渡します。テストの書き方は関連記事「Angular テスト Vitest 入門|v22の書き方・移行・実行結果つき」で扱っています。

Q. 本番だけでエラーが出ます。 A. 本番ビルドでは、ルート定義のチェック(NG04014)が動かず、先頭の / や pathMatch の付け忘れが黙って通りました。開発ビルドで起動して、NG04014 が出ないかを確かめます。リロードで 404 のときは、上のサーバーの設定です。

まとめ

  • NG04002 は「URL に合うルートが無い」。URL Segment の文字列とルート定義を見比べる
  • 本番ビルドでは NG04002: 'user' だけになる。ログは番号で探す
  • routerLink は / で始めないと今いるルートの子を探す。navigate() は逆で、relativeTo が無ければ一番上から
  • 子を持つルートに pathMatch: 'full' を付けると、子に届かない
  • ( ) は outlet の区切り。パスに入れるなら %28 %29 に
  • 404 画面は { path: '**', component: NotFound } を最後に。先頭に置くと全部 404 になる
  • / で始まる path・pathMatch の付け忘れは、開発ビルドでだけ NG04014 で止まる
  • リロードで 404 はサーバー側。index.html に戻す設定を入れる

参考・出典

確認日はいずれも 2026年10月13日です。

  • Angular「Common routing tasks」(Displaying a 404 page):https://angular.dev/guide/routing/common-router-tasks
  • Angular「Redirecting routes」:https://angular.dev/guide/routing/redirecting-routes
  • Angular「RouterLink」:https://angular.dev/api/router/RouterLink
  • Angular「withDebugTracing」:https://angular.dev/api/router/withDebugTracing
  • Angular「Deployment」(Routed apps must fall back to index.html):https://angular.dev/tools/cli/deployment
  • angular/angular Issue #50787「Parentheses in url cause Error: NG04002」:https://github.com/angular/angular/issues/50787

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「NG04002 Cannot match any routesの直し方|原因一覧」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?