Azure Functions「No job functions found」原因と解決策|dotnet-isolated設定とチェックリスト

Azure Functions をローカルで起動したのに、ログに「No job functions found」と出て関数が1つも表示されない…。 .NET 7 の Isolated Worker でよくある原因は、コードではなく設定側にあります。この記事では、FUNCTIONS_WORKER_RUNTIME の正しい値から、csproj/Program.cs/デバッグ設定の落とし穴まで、再現しやすいポイント順に具体的に整理します。

目次

「No job functions found」とは何が起きている状態か

このメッセージは「関数が存在しない」ことを断定しているわけではなく、Azure Functions ホスト(Functions Host)が実行対象として読み込める関数メタデータを1件も見つけられなかったときに出る代表的なエラーです。とくに .NET Isolated Worker(分離プロセス)モデルでは、ホスト本体(func.exe / Functions Host)と、あなたの関数アプリ(.NET の実行プロセス)が別プロセスで動きます。

そのため、コードに [Function] を付けていても、ホスト側が「このアプリはどのワーカーで動くべきか」を判断できない・起動できない状態だと、結果として関数が0件扱いになります。

No job functions found.
Try making your job classes and methods public.
If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.)
make sure you've called the registration method...

この文面には「public にして」や「拡張の登録を」といったヒントが並びますが、.NET Isolated ではまずランタイム設定がズレていないかを見るのが近道です。

最優先で確認する原因:FUNCTIONS_WORKER_RUNTIME が dotnet-isolated になっていない

.NET 7 / Isolated Worker で「No job functions found」が出るケースで、最も多いのがFUNCTIONS_WORKER_RUNTIME の未設定・誤設定です。ローカル実行では local.settings.json(または環境変数)に、Isolated 用の値として dotnet-isolated を設定する必要があります。

正しい local.settings.json の例

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
  }
}

次のような状態だと、ホストは「このアプリがどのワーカー用か分からない/別のワーカーだと思い込む」ため、関数メタデータの読み込みが進まず、0件判定になりやすくなります。

  • FUNCTIONS_WORKER_RUNTIME がそもそも無い
  • FUNCTIONS_WORKER_RUNTIME が dotnet のまま(in-process の値)
  • 環境変数やデバッグ設定で FUNCTIONS_WORKER_RUNTIME が別の値に上書きされている
  • 移行時に local.settings.json をコピーしてきて古い値のまま

どこに設定すべきか(ローカル/Azure/デバッグ)

場面設定する場所ポイント
ローカル開発local.settings.jsonCore Tools が読み込み、プロセスの環境変数として注入される
Azure にデプロイ後Function App のアプリ設定(Application settings)local.settings.json はデプロイされない。クラウド側にも同じキーが必要
VS/VS Code デバッグデバッグプロファイルや launch.json の環境変数同名キーがあると local.settings.json を上書きすることがある

よく使うワーカー名(値)の早見表

言語/モデルFUNCTIONS_WORKER_RUNTIME の例メモ
.NET in-processdotnet古いモデル。分離プロセスではない
.NET Isolated Workerdotnet-isolated.NET 6/7/8 などで主流。今回の対象
Node.jsnodeJavaScript/TypeScript の実行
PythonpythonPython 実行。プログラミングモデルで原因が変わることあり
PowerShellpowershellPowerShell 実行

なぜ未設定・誤設定で関数が0件になるのか

.NET Isolated の仕組みをざっくり押さえると、切り分けが一気に楽になります。ポイントは「ホストがワーカーを起動し、ワーカーが関数メタデータを提示してはじめて、ホストが“関数一覧”を作れる」という流れです。

  1. Azure Functions Host(Core Tools)が起動する
  2. local.settings.json / 環境変数から FUNCTIONS_WORKER_RUNTIME を読む
  3. 指定されたランタイムのワーカープロセスを起動しようとする(Isolated なら .NET の別プロセス)
  4. ワーカーが起動し、ビルド成果物(関数メタデータ)を読み、ホストへ関数情報を返す
  5. ホストが「検出した関数」をログに表示して待ち受け開始

この流れの2〜3で詰まると、ホスト側は「関数が無い」ように見えてしまい、結果として「No job functions found」が出ます。Isolated へ移行した直後に発生しやすいのは、移行前の dotnet のまま残っているケースです。

最短で直す手順(ローカル)

まずは “直撃率が高いところ” だけに絞って手を動かします。

  1. 実行中の Functions Host を停止する(ターミナルなら Ctrl + C)
  2. プロジェクト直下の local.settings.json を開き、FUNCTIONS_WORKER_RUNTIME を dotnet-isolated にする
  3. 可能なら bin と obj を削除してクリーンにする(挙動が怪しいときの保険)
  4. プロジェクト直下で func start(不安なら func start --verbose)
  5. ログに “関数名が列挙される” ことを確認する

起動ログでは、最終的に「Functions:」のような形で関数名が列挙されます。ここが空のままなら、次の章のチェックに進みます。

設定を見ても直らない場合のチェックリスト(原因の優先度順)

「FUNCTIONS_WORKER_RUNTIME は確実に dotnet-isolated」なのに関数が0件のままなら、原因は大きくビルド生成物、起動コード、関数定義、設定の参照先に分かれます。よくあるものから順に潰せるよう、一覧にまとめます。

観点よくある症状確認ポイント対処の方向性
設定が参照されていない直したはずなのに変化がないfunc start を実行したカレントディレクトリがプロジェクト直下か正しいフォルダで起動。VS/VS Code の「作業ディレクトリ」も確認
環境変数で上書きPCやCIでだけ再現するOS環境変数、launchSettings.json、デバッグプロファイルFUNCTIONS_WORKER_RUNTIME の重複定義を削除・統一
csproj / SDK 設定ビルドは通るが関数0件Microsoft.Azure.Functions.Worker.Sdk を Analyzer として参照しているかSDK参照を修正。OutputType を Exe に
Program.cs の起動コードホストは起動するがワーカーが不安定ConfigureFunctionsWorkerDefaults() と Run()/RunAsync()テンプレートの最小構成に戻して比較
関数クラス側の定義特定の関数だけ出ない/全滅クラス/メソッドが public、[Function]、トリガー属性サンプルの HttpTrigger を1つ追加し、発見できるか確認
Core Tools の世代古いPCでだけ失敗func --version が v4 系かCore Tools を更新(npm / MSI など)

.NET Isolated で押さえるべきプロジェクト設定(csproj)

.NET Isolated では、ビルド時に「関数メタデータ(どのメソッドが関数か)」を生成する仕組みが重要です。この生成に関わるのが Microsoft.Azure.Functions.Worker.Sdk です。ここが抜けている・参照の仕方が違うと、ホストが読み込むメタデータが作られず、結果として 0 件になります。

csproj の最小イメージ

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>






ポイントは次のとおりです。

  • OutputType は Exe(Isolated はコンソールアプリとして起動される)
  • Worker.Sdk はAnalyzer として参照する(OutputItemType="Analyzer")
  • HTTP などのトリガー拡張は Isolated 用の Worker.Extensions.* を参照する

csproj で起きがちな落とし穴

落とし穴起きること対策
Worker.Sdk が無い関数メタデータが生成されず 0 件になりやすいテンプレート通りに追加し、Analyzer 指定も入れる
OutputType が LibraryIsolated として起動しづらく、挙動が不安定になりがちExe にする
パッケージの世代がバラバラビルドは通っても実行時の読み込みで失敗することがあるMicrosoft.Azure.Functions.Worker* を近い世代で揃える

Program.cs の最小構成をまず再現する

起動コードをカスタムしている場合(独自 DI、独自ログ、ミドルウェアなど)、原因の切り分けを難しくすることがあります。まずは “動く最小構成” に寄せて、関数が検出されるかを確認しましょう。

最小の Program.cs 例

using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.Build();

host.Run();

この形で関数が認識されるなら、追加した設定(ConfigureServices、ログ設定、ミドルウェア)を少しずつ戻して、どこで 0 件になるかを特定できます。

関数クラス側の基本(public / 属性 / トリガー)

「設定が正しいのに 0 件」のとき、次に多いのが関数定義の細かい条件を満たしていないケースです。エラーメッセージにもあるとおり、クラスやメソッドのアクセス修飾子が原因になることがあります。

HttpTrigger の最小例(検出テスト用)

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using System.Net;

public class PingFunction
{
[Function("Ping")]
public HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req)
{
var res = req.CreateResponse(HttpStatusCode.OK);
res.WriteString("pong");
return res;
}
}
  • クラスは public
  • メソッドは public
  • [Function("名前")] が付いている
  • トリガー属性(ここでは [HttpTrigger])が付いている

まずこの “確実に単純な1本” を追加し、関数一覧に出るかを見ると、プロジェクト全体の問題か、特定の関数の問題かを切り分けられます。

local.settings.json が効かない・別の値で上書きされるパターン

ローカルでのハマりどころは「正しい設定を書いたつもりなのに、ホストがその設定を読んでいない」ことです。とくに VS Code / Visual Studio では、デバッグ設定や環境変数が絡むため、上書きが起きやすくなります。

どこで上書きされるか(代表例)

場所例チェック方法
OS の環境変数Windows の「環境変数」、Linux の exportターミナルで echo %FUNCTIONS_WORKER_RUNTIME% / echo $FUNCTIONS_WORKER_RUNTIME
Visual Studio のデバッグプロファイルプロジェクトの「デバッグ」設定起動プロファイルの環境変数一覧を確認
VS Codelaunch.json / settings.jsonenv セクションに同名がないか確認
CI/CDGitHub Actions / Azure DevOps の変数ジョブの環境変数ログ、Variables 設定を確認

上書きが疑わしいときは、起動時の環境変数をいったん最小化し、local.settings.json の値だけで起動してみるのが確実です。

ビルド成果物を確認して「関数メタデータが生成されているか」を見る

.NET Isolated では、ビルドの結果として出力フォルダに関数メタデータが生成されます。ここが無い、または古いままの場合、ホストは関数を認識できません。目視チェックとしては、次のような観点が有効です。

  • bin/Debug/net7.0/(構成により Release など)に、関数に関連するメタデータファイルが出力されているか
  • 関数を追加・変更したのに、出力が更新されていない(ビルドが走っていない)状態になっていないか
  • 古い bin/obj が残っていて挙動が怪しい場合は、一度削除してクリーンビルドする

見つからない場合は、Worker.Sdk の参照漏れや、Analyzer 指定の不足が疑わしいポイントです。

拡張(Extensions)系の注意点:トリガー/バインディングの NuGet が揃っているか

エラーメッセージに「binding extensions を登録しているか」と出るため混乱しがちですが、Isolated では “登録メソッドを呼ぶ” というより、必要な拡張パッケージを参照してビルド時にメタデータが生成される状態が重要です。

例えば HTTP トリガーなら Microsoft.Azure.Functions.Worker.Extensions.Http、Timer なら Timer 用の拡張、といった具合に、使う属性を提供するパッケージが入っていないとそもそもコンパイルできません。コンパイルは通るのに 0 件という場合は、拡張よりも先に、本記事のチェックリスト(ランタイム設定、SDK、起動コード、public/属性)を優先してください。

.NET 7 のサポート終了と、今後のおすすめ(.NET 8 への移行)

.NET 7 は 2024年5月14日でサポート終了(EOL)となっているため、長期運用や新規開発では .NET 8(LTS)+ Isolated Worker をベースにするのが安全です。ローカルの「No job functions found」を解決しても、ランタイムや SDK の更新を放置すると、将来的に別の落とし穴(Core Tools/拡張の互換性、デプロイ先の設定差分)に引っかかりやすくなります。

.NET 8 へ寄せるときの観点

観点チェック内容補足
TargetFrameworknet8.0 に変更LTS を選ぶと保守が楽
Functions ランタイムAzureFunctionsVersion は v4 のままFunctions v4 は Isolated と相性が良い
パッケージWorker / Worker.Sdk / Extensions を更新同一世代で揃えるとトラブルが減る
設定FUNCTIONS_WORKER_RUNTIME は dotnet-isolated.NET のバージョンが変わっても値は同じ

補足:Python でも同じエラーが出るが、原因は別物になり得る

「No job functions found」はホスト側の汎用メッセージなので、言語が変わっても表示されます。ただし Python の場合は、.NET のようなランタイム値の不一致ではなく、デコレータ指定ミスなどで関数が列挙されないケースが報告されています。

Python(新しいプログラミングモデル)での例:AuthLevel の大文字小文字

Python の Functions プログラミングモデルで FunctionApp() を使う場合、auth_level には列挙型の定数を指定します。ここで Anonymous のように書くと認識されず、結果として関数 0 件扱いになることがあります。

import azure.functions as func

app = func.FunctionApp()

@app.route(route="HttpExample", auth_level=func.AuthLevel.ANONYMOUS)
def HttpExample(req: func.HttpRequest) -> func.HttpResponse:
    return func.HttpResponse("ok")
ミス例正しい例ポイント
func.AuthLevel.Anonymousfunc.AuthLevel.ANONYMOUS列挙型は大文字定数。Python では大小文字が区別される

このように、同じエラーメッセージでも「言語・モデルによって原因が違う」ことがあるため、最終的には自分の構成(.NET Isolated / Python / Node など)に合わせてチェックするのが確実です。

再発防止のコツ:設定と実行環境を“見える化”しておく

ローカル開発では、チームや環境差で「なぜか自分のPCだけ動かない」が起きがちです。再発防止のために、次の運用を取り入れると事故が減ります。

  • 移行時の差分を残す:in-process から Isolated へ移行したら、local.settings.json とデバッグ設定の差分を Pull Request で明示する
  • README に前提条件を書く:「Core Tools v4」「FUNCTIONS_WORKER_RUNTIME=dotnet-isolated」など、必要条件を短く固定で書く
  • サンプル関数を1本残す:Ping 用 HttpTrigger を残しておくと、0件になったときの切り分けが速い
  • CI でも起動確認する:ビルド後に func start 相当のチェック(またはメタデータ生成の検証)を入れると、設定漏れを早期に検出できる

まとめ:.NET Isolated の「No job functions found」は設定から疑う

  • .NET Isolated Worker で最も多い原因は FUNCTIONS_WORKER_RUNTIME が dotnet-isolated になっていないこと
  • 次に、csproj(Worker.Sdk / OutputType)、Program.cs(ConfigureFunctionsWorkerDefaults)、関数定義(public/属性)を優先度順に確認する
  • 同じエラーメッセージでも、Python など別言語では原因が違う場合があるため、モデル別の書式ミスにも注意する

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次