以下の内容は 2026 年 10 月 23 日時点の Supabase のドキュメントに基づきます。最新の制限と設定はそちらを確認してください。最初のテストメールの送信や送信元の設定などの基本は、Supabase Auth のメールをテストする から始めてください。
メールが届かない
組み込みの送信元はテスターにメールを送りません。 Supabase 独自のメールサービスはプロジェクトのチームのメンバーにしか配信せず、1 時間に最大 2 通です。あなたはチームにいるので動きますが、ほかの人には「Email address not authorized」で拒否されます。Authentication の Emails でカスタム SMTP を設定してください。
SMTP プロバイダーがまだサンドボックスにあります。 新しい Resend アカウントはドメインを検証するまで自分のアドレスにしか送信せず、Amazon SES は検証済みのアドレスにしか送信しません。Supabase はメールを渡しますが、プロバイダーが黙って破棄します。
再要求が早すぎます。 既定では、各ユーザーが受け取れる確認、マジックリンク、コード、リセットのメールは 60 秒に 1 通、各 IP アドレスが送れるサインアップとサインインのリクエストは 5 分に 30 回です。すぐに再試行するテストや、1 台の CI マシンから実行するスイートはこれに引っかかり、429 が返ります。ステージング用プロジェクトでは Authentication の Rate Limits で上限を上げてください。
アドレスにすでにアカウントがあります。 誰がサインアップしたかを明かさないよう、Supabase は確認済みのアドレスのサインアップに対し、ID を持たないユーザーで成功したかのように応答し、メールを送りません。アドレスを使い回すテストは、届かないメールを待ち続けます。実行ごとに新しいアドレスを使ってください。
Confirm email がオフになっています。 その場合、サインアップするとすぐにユーザーがサインインされ、何も送られません。Authentication の Sign In / Providers、Email を確認してください。開発中にオフにして、そのまま戻し忘れることがよくあります。
リンクが無効、または期限切れと表示される
リンクをクリックすると、アドレスバーに error_code=otp_expired(「Email link is invalid or has expired」)が付いた状態でアプリに移動します。
- すでに使われています。 リンクは 1 回だけ使え、既定で 1 時間有効です。別のメールを要求すると前のリンクは置き換えられるので、最新のものを使ってください。
- スキャナーが先に開きました。 一部のメールサービスや、リンクスキャナーなどの企業向けセキュリティツールは、新しいメール内のすべてのリンクを開いて確認します。これにより、本人がクリックする前に 1 回限りのリンクが使い切られます。Supabase は、代わりに 6 桁のコードを送る(テンプレートでは
{{ .Token }})か、本人がボタンを押して確認する自分のページにリンクすることを勧めています。Proxy Mail QA はリンクを開かないため、テストではリンクが動くのに実際のユーザーで失敗するなら、スキャナーが原因の可能性が高いです。
リンクは開くが、誰もサインインしていない
別のブラウザで開かれました。 Supabase のサーバーサイドヘルパーが使う PKCE フローでは、サインアップを始めたブラウザがリンクに必要なシークレットを保持します。別のブラウザ、プライベートウィンドウ、別のデバイスでリンクを開くと交換が失敗し、多くの場合「both auth code and code verifier should be non-empty」と表示されます。テスターはサインアップしたブラウザでリンクを開いてください。どこでも動くリンクにするには、{{ .TokenHash }} からリンクを作成し、サーバーで verifyOtp を使って検証します。
サインインを完了する処理がありません。 リンクはアドレスに code(またはトークン)が付いた状態でアプリに到達し、どこかのページがそれをセッションに交換する必要があります。そのルートがないと、本人にはサインアウトした状態のホームページが表示されます。リンク先のページが exchangeCodeForSession、またはトークンハッシュを使って verifyOtp を呼んでいるか確認してください。
サーバーからセッションが見えません。 既定のリンクはアドレスの # の後ろにセッションを置くため、ブラウザしか読めません。サーバーレンダリングのアプリには、上記のトークンハッシュのリンクが必要です。
リンクが localhost や間違った環境に向かう
Site URL の初期値は http://localhost:3000 で、Redirect URLs の一覧にない redirectTo はすべてこれにフォールバックします。Site URL をデプロイ済みのアプリに設定し、すべての環境を一覧に追加してください。詳しくは メールが localhost にリンクする理由 を参照してください。Proxy Mail QA はアドレスの行でそのようなリンクにフラグを付けます。
サインアップが「Database error saving new user」で失敗する
データベース内の何かが新しいユーザーを拒否しています。ほぼ必ず auth.users のトリガーで、たとえば profiles に行を作成するものです。よくある原因は、書き込み先のテーブルや列が存在しない、関数が security definer でないため public に書き込めない、埋める列が not null なのにサインアップでその値が送られていない、などです。Supabase の Auth と Postgres のログに本当のエラーが表示されます。
扱いにくい値でもテストしてください。アポストロフィを含む名前、別の文字体系、255 文字の名前は、通常のテストデータでは届かないプロフィールの列を壊すことがあります。珍しい名前とパスワード に試すべき一覧があります。
リセットメールは届くが、パスワードが変わらない
リセットリンクは本人を復旧用セッションでサインインさせ、PASSWORD_RECOVERY イベントを発生させます。アプリはそれを検知し、新しいパスワードのフォームを表示して、その値で updateUser を呼ぶ必要があります。そうしないと、本人は古いパスワードのままサインインした状態になるだけです。PKCE では、リンクを要求したブラウザで開く必要もあります。詳しくは パスワードリセットのメールをテストする を参照してください。
キャプチャが自動テストをブロックする
キャプチャ保護(Authentication、Attack Protection)がオンだと、すべてのサインアップとサインインにキャプチャのトークンが必要になり、自動化されたブラウザは通過できません。ステージング用プロジェクトでは、常に通過するキャプチャプロバイダーのテストキーを使い、本物のキーは本番用に取っておいてください。
ローカルの Supabase では動くが、ホスト型のプロジェクトでは動かない
Supabase CLI はローカルのメールを独自のメールビューア(通常は localhost:54324)で受け止め、テンプレートを supabase/config.toml から読み込みます。ホスト型のプロジェクトでは、ダッシュボードのテンプレート、送信元、レート制限が使われます。公開前に、メールを受信できるアドレス宛てに実際のメールを送り、ホスト型のステージング用プロジェクトでテストしてください。
一度にすべて確認する
- シナリオごとに新しい Proxy Mail QA アドレスを作成します。新規ユーザー、既存ユーザー、パスワードリセット、マジックリンクなどです。
- アプリでフローを進めます。数秒以内に、コードやリンクがアドレスの行に表示されます。
- 行を確認します。localhost へのリンクにはフラグが付き、受信トレイにはメールにリンクの有効期限が書かれているかどうかが表示されます。
- サインアップしたのと同じブラウザでリンクを開き、正しいサイトでサインインしているか確認します。
Lovable、Bolt、v0 で作りましたか? バイブコーディングで作ったサインアップとログインの問題 では、こうしたアプリがこれらに加えてよく間違える点を扱っています。