使い方ガイド公開日 読了目安 約12分

cron が動かない原因チェックリスト|手動では動くのに失敗する理由とログの確認方法

crontab に書いたはずのバッチが動いていない。ターミナルで手で実行すると成功するのに、cron からだと何も起きない。cron のトラブルは、エラーがどこにも表示されないまま静かに失敗することが多く、原因を探すのに時間がかかりがちです。この記事では、cron が動かないときに確かめる順番を「式」「cron 本体」「ログ」「実行環境」「ファイルと権限」「タイムゾーン」に分けて整理し、手動では動くのに cron だと失敗する典型的な理由と、その直し方をまとめます。

まず切り分け:「cron が動いていない」のか「コマンドが失敗している」のか

「cron が動かない」と一口に言っても、原因は大きく 2 つに分かれます。1 つは、そもそも cron がその時刻にコマンドを起動していないケース。もう 1 つは、cron は予定どおり起動しているのに、コマンドの中で失敗しているケースです。どちらなのかで調べる場所がまったく違うので、最初に切り分けます。

  1. 1

    ログに起動の記録があるかを見る

    後で説明する cron のログに、その時刻に「CMD (コマンド)」の行が出ていれば、cron は起動しています。原因はコマンド側です。行がなければ、式・cron 本体・ファイルの書き方を疑います。

  2. 2

    1 分ごとのテスト行を足してみる

    crontab -e で「* * * * * date >> /tmp/cron-test.log 2>&1」を一時的に追加し、1〜2 分待って /tmp/cron-test.log に時刻が増えていくかを見ます。増えていれば cron 自体は正常に動いています。確認が終わったら必ず削除します。

  3. 3

    本番の行の時刻を近い時刻に変えて試す

    日次や週次の予定は、次に動くまで待つと何日もかかります。テスト中だけ時刻を数分後に変え、結果を見てから元に戻すと、すぐに確かめられます。

式の書き間違いで「動いていない」ように見えるパターン

cron は式として正しければ、意図と違っていても文句を言わずにその時刻に動きます。「動かない」と思っていたら、実は想定外の日時に動いていた、ということも少なくありません。まず式そのものを疑いましょう。

書いた式意図実際の動き
0 9 31 * *毎月末日31 日がない 2・4・6・9・11 月は動かない
0 9 30 2 *2 月の末日2 月 30 日は存在しないので一度も動かない
0 9 1-7 * 1第 1 月曜毎週月曜と毎月 1〜7 日に動く(OR)
30 9 * * *(UTC のサーバー)日本時間 9:30日本時間 18:30 に動く
9 30 * * *9:30時の欄に 30 は書けず、エラーで読み込まれない
* 3 * * *毎日 3 時に 1 回3:00〜3:59 の毎分、60 回動く

日と曜日の組み合わせや月末の書き方は特に間違えやすいので、cron の日と曜日の OR と第 n 曜日・月末の書き方で詳しく解説しています。cron 式チェッカーに crontab の行を貼れば、意味を日本語に訳して次の実行日時を 10 件並べるので、「いつ動く予定になっているか」をすぐに確認できます。

cron 本体の状態とログの確認方法

式が正しいのに起動の記録がない場合は、cron のサービスが止まっていないか、ログにエラーが出ていないかを確認します。ディストリビューションによってサービス名とログの場所が違います。

確認することUbuntu・DebianRHEL・CentOS・Rocky・Amazon Linux
サービスの状態systemctl status cronsystemctl status crond
サービスの起動sudo systemctl enable --now cronsudo systemctl enable --now crond
ログ(ファイル)grep CRON /var/log/syslogsudo cat /var/log/cron
ログ(journal)journalctl -u cron --since todayjournalctl -u crond --since today
  • 「(ユーザー名) CMD (コマンド)」の行:その時刻にコマンドを起動した記録。これがあれば cron は正常
  • 「(CRON) info (No MTA installed, discarding output)」:コマンドが何か出力したが、メールで送る仕組みがないので捨てた、という意味。エラーメッセージがここで消えている可能性が高い
  • 「(*system*) … WRONG FILE OWNER」「INSECURE MODE」:/etc/cron.d などのファイルの持ち主や権限がおかしく、読み込まれていない
  • 「bad minute」「bad hour」「errors in crontab file」:式の書式エラー。その行は読み込まれていない

手動では動くのに cron だと失敗する 5 つの理由

ログに起動の記録があるのに結果が出ていないなら、コマンドが cron の環境で失敗しています。cron は、ログインしたときのシェルとは違う、ごく最小限の環境でコマンドを実行します。手で試すと成功するのに cron だと失敗するのは、ほとんどがこの差です。

原因症状直し方
PATH が短いcommand not found(/usr/local/bin や ~/.local/bin のコマンド)コマンドを絶対パスで書く。または crontab の先頭に PATH= を書く
シェルが /bin/shbash の書き方(source、[[ ]]、配列)でエラースクリプトの先頭に #!/bin/bash を書き、スクリプトとして呼ぶ
.bashrc などを読まない環境変数(API キーや言語のバージョン管理)が空必要な変数をスクリプト内で設定するか、crontab の先頭に書く
作業ディレクトリがホーム相対パスのファイルが見つからないスクリプトの最初で cd /path/to/dir するか、絶対パスにする
% が改行になるdate +%Y%m%d の途中でコマンドが切れるcrontab の中では \% とエスケープする

cron と同じ環境で試すには、「env -i HOME=$HOME PATH=/usr/bin:/bin SHELL=/bin/sh /bin/sh -c 'コマンド'」のように、環境変数をほぼ空にしてコマンドを実行してみるのが近道です。ここで失敗すれば、原因は環境の差だと分かります。

% の問題は気づきにくいので特に注意が必要です。crontab のコマンド部分では、% が「ここで改行、残りは標準入力に渡す」という意味になります。「tar czf /backup/$(date +%Y%m%d).tar.gz /data」のような行は、% の手前でコマンドが切れて失敗します。「date +\%Y\%m\%d」とエスケープするか、処理をシェルスクリプトにまとめて crontab からはスクリプトを呼ぶだけにすると確実です。

ファイル・権限・改行コードの落とし穴

crontab の書き方そのものは正しくても、ファイルの置き方や権限が原因で読み込まれていない、実行できない、ということもあります。次の項目を順に確認します。

  • スクリプトに実行権限があるか:ls -l で x が付いているか確認し、なければ chmod +x script.sh。または sh script.sh のようにシェル経由で呼ぶ
  • 1 行目の #! が正しいか:#!/bin/bash のパスが実在するか。Windows で編集したファイルは行末が CRLF になり「/bin/bash^M: bad interpreter」で失敗するので、dos2unix などで LF に直す
  • crontab の最後の行に改行があるか:最終行に改行がないと、その行が無視される実装がある
  • /etc/cron.d のファイルにユーザー名の欄があるか:/etc/crontab と /etc/cron.d/ のファイルは「分 時 日 月 曜日 ユーザー名 コマンド」の 7 つ以上の欄が必要
  • /etc/cron.d のファイル名と権限:Debian・Ubuntu ではファイル名に . を含むファイル(backup.cron など)は読まれない。持ち主は root、ほかのユーザーが書き込めない権限(644)にする
  • cron.allow・cron.deny:/etc/cron.allow があると、そこに書かれたユーザーしか crontab を使えない

タイムゾーンのずれ:9 時間ずれて動いていないか

「動かない」の正体が「9 時間ずれて動いている」だったということはよくあります。cron は、cron が動いているサーバー(コンテナ)のタイムゾーンで時刻を読みます。クラウドのサーバーやコンテナのイメージは初期設定が UTC のことが多く、日本時間のつもりで書いた時刻より 9 時間遅れて動きます。

  1. 1

    サーバーのタイムゾーンを確かめる

    date や timedatectl を実行し、表示が JST か UTC かを見ます。UTC なら、日本時間から 9 時間引いた時刻で書くか、タイムゾーンを変更します。

  2. 2

    タイムゾーンを変えたら cron を再起動する

    sudo timedatectl set-timezone Asia/Tokyo で変更できますが、すでに動いている cron は古いタイムゾーンのままのことがあります。sudo systemctl restart cron(RHEL 系は crond)で再起動します。

  3. 3

    1 行だけ別のタイムゾーンにしたいとき

    RHEL 系で使われる cronie は、crontab に CRON_TZ=Asia/Tokyo と書くと、その後の行を指定したタイムゾーンで読みます。ただし Debian・Ubuntu の標準の cron では効かないので、時刻を UTC に直して書くほうが確実です。

GitHub Actions・AWS EventBridge・Kubernetes など、サーバーの外で cron 式を読む仕組みでも同じずれが起きます。GitHub Actions は常に UTC なのでGitHub Actions の cron を日本時間で動かす方法を、EventBridge はEventBridge の cron 式の書き方を参照してください。

次に失敗したときすぐ分かるようにする

原因が分かって直ったら、次に同じことが起きたときにすぐ気づけるようにしておくと、トラブルの調査時間が大きく減ります。

  • 出力を必ずログに残す:行の末尾に >> /var/log/myjob.log 2>&1 を付け、エラーも含めて追記する。ログが大きくなりすぎないよう logrotate も設定する
  • MAILTO を設定する:crontab の先頭に MAILTO=you@example.com と書くと、出力があったときにメールで届く(メールを送る仕組みがサーバーに必要)
  • 二重起動を防ぐ:前回の処理が終わる前に次が始まると不具合の元になる。flock -n /tmp/myjob.lock コマンド のようにロックをかける
  • 成功を外から監視する:処理の最後に監視サービスの URL を叩く「死活監視(ハートビート)」を入れると、動かなかったことにも気づける
  • crontab のバックアップ:crontab -l > ~/crontab.bak を定期的に取り、設定の変更履歴を残す

crontab の書き方や記号の意味をもう一度整理したいときはcrontab の書き方と早見表が役立ちます。設定を変えるたびに cron 式チェッカーで次の実行日時を確かめておけば、「書いたつもりと違う時刻に動く」タイプのトラブルは事前に防げます。

よくある質問

crontab に書いたのに実行されないときは、まず何を確認すればいいですか?
最初に cron のログ(Ubuntu なら grep CRON /var/log/syslog、RHEL 系なら /var/log/cron)を見て、その時刻に CMD の行があるかを確認します。行があればコマンド側の失敗、なければ式の書き間違いや cron のサービスの停止を疑います。「* * * * * date >> /tmp/cron-test.log」を一時的に足すと、cron 自体が動いているかをすぐに確かめられます。
手動では動くのに cron だと動かないのはなぜですか?
cron は PATH が /usr/bin:/bin 程度しかない最小限の環境で、/bin/sh を使い、.bashrc なども読まずにコマンドを実行するためです。コマンドを絶対パスで書く、必要な環境変数をスクリプト内で設定する、作業ディレクトリに cd する、% を \% とエスケープする、といった対応で解決することがほとんどです。
cron のログはどこで確認できますか?
Ubuntu・Debian では /var/log/syslog に記録されるので grep CRON /var/log/syslog で絞り込みます。RHEL・CentOS・Rocky Linux などでは /var/log/cron です。systemd の環境なら journalctl -u cron(RHEL 系は -u crond)でも確認できます。
cron の実行時刻が 9 時間ずれるのはなぜですか?
cron がサーバーのタイムゾーンで時刻を読んでいて、そのサーバーが UTC に設定されているためです。日本時間は UTC より 9 時間進んでいるので、日本時間のつもりで書いた時刻より 9 時間遅れて動きます。タイムゾーンを Asia/Tokyo に変えて cron を再起動するか、UTC の時刻に直して書きます。
/etc/cron.d に置いたファイルが動きません。
/etc/cron.d のファイルは、5 つの時刻の欄とコマンドの間に実行するユーザー名の欄が必要です。また Debian・Ubuntu ではファイル名に . を含むと読み込まれず、持ち主が root でない、ほかのユーザーが書き込める権限になっている場合も無視されます。ログの WRONG FILE OWNER や INSECURE MODE の表示も確認してください。

この記事で紹介したツール

あわせて読みたい

仕組み解説約11分

cron の日と曜日は OR になる|第 2 月曜・月末・最終金曜・隔週の正しい書き方

「毎月第 1 月曜の 9 時」のつもりで「0 9 1-7 * 1」と書いたら、毎週月曜に加えて毎月 1〜7 日の毎日にも動いてしまった。cron でとても多いこの失敗は、日と曜日の両方を指定すると「どちらか」に当てはまる日に動くという、cron 独特のルールが原因です。この記事では、日と曜日が OR になる仕組みと例外、crontab で第 n 曜日・月末・最終金曜・隔週を正しく動かす書き方、AWS EventBridge や Spring で使える L・#・W の書き方までを、実際の実行日付の例つきで解説します。

記事を読む →
使い方ガイド約11分

GitHub Actions の cron を日本時間で動かす|UTC 変換の早見表と曜日ずれ・遅延の対策

GitHub Actions の schedule に「0 9 * * 1-5」と書いたのに、ワークフローが動いたのは日本時間の夕方 6 時だった。これは書き間違いではなく、GitHub Actions の cron が必ず UTC(協定世界時)で読まれるためです。この記事では、日本時間(JST)の時刻を UTC の cron 式に直す計算と早見表、朝 0〜8 時を指定したときに起きる「曜日・日付が前の日にずれる」問題、1 行で書けないときの 2 行への分け方、そして schedule が遅れる・動かないときの原因と対策までをまとめます。

記事を読む →
使い方ガイド約11分

EventBridge の cron 式の書き方|? の意味・曜日の数字・日本時間の指定と crontab からの書き換え

AWS で Lambda や ECS のタスクを定期実行するときに使う EventBridge の cron 式は、Linux の crontab と似ているようで、欄の数・? の使い方・曜日の数字・タイムゾーンが少しずつ違います。crontab の感覚で「0 9 * * 1-5」と書くとエラーになり、曜日の数字をそのまま移すと 1 日ずれ、時刻は UTC で読まれて 9 時間ずれる、とつまずきどころが重なります。この記事では、EventBridge の cron 式の 6 つの欄と ? のルール、曜日の数字、L・W・# の使い方、rate 式との違い、ルールと Scheduler での日本時間の扱い、crontab・Kubernetes・Spring・systemd との書き換え表までをまとめます。

記事を読む →