Supabase Signup が失敗する:gen_random_bytes() does not exist
❗ 問題現象
ユーザー登録(Signup)が失敗し、以下のエラーが発生します。
function gen_random_bytes(integer) does not exist
No function matches the given name and argument types
current transaction is aborted, commands ignored until end of transaction block
主な症状:
- 新規ユーザーを作成できない
- Supabase Auth の Signup が継続的に失敗する
🔄 実行フロー
Client Signup
↓
auth.users INSERT
↓
AFTER INSERT Trigger
↓
create_profile_for_new_user()
↓
gen_random_bytes()
🔍 原因分析
gen_random_bytes() は PostgreSQL の コア組み込み関数ではありません。 これは pgcrypto 拡張 により提供される関数です。 Supabase 環境では、pgcrypto 関数は通常 extensions schema に配置されています: extensions.gen_random_bytes()
Supabase の Signup 処理では: auth.users → trigger → カスタム関数 が実行され、この関数は多くの場合 SECURITY DEFINER として動作します。
SECURITY DEFINER 関数では、 呼び出し元の search_path は継承されません。 代わりに PostgreSQL は、 関数作成時に記録された search_path を使用します。
この search_path に extensions schema が含まれていない場合、 pgcrypto 拡張がインストール済みでも gen_random_bytes() を解決できません。 この問題は拡張未インストールではなく、 関数解決(function lookup)段階 で発生します。
🎯 根本原因(Root Cause)
Supabase Auth Trigger は通常 SECURITY DEFINER で実行されます。
この場合:
- 関数作成時の search_path が使用される
- extensions などの非デフォルト schema が不可視になる
- schema 未指定の関数呼び出しが失敗する
つまり問題は Supabase Auth ではなく、 SECURITY DEFINER 実行環境における schema 可視性にあります。
✅ 解決方法
schema を明示する
extensions.gen_random_bytes(16)
-- または
pgcrypto.gen_random_bytes(16)
関数内で search_path を設定する
CREATE OR REPLACE FUNCTION ...
SECURITY DEFINER
SET search_path = public, extensions;
代替案:random()
random()
⚠️ 注意:
random() は暗号学的に安全な乱数ではありません。
token や識別子などのセキュリティ用途には使用しないでください。
🛡️ ベストプラクティス
Auth Trigger では以下を避ける:
- 拡張関数への依存
- schema を跨ぐ呼び出し
- 複雑なビジネスロジック
Trigger は以下のみに限定する:
- シンプルな INSERT
- 最小限の初期データ生成
📌 まとめ
gen_random_bytes() エラーは 関数が存在しないことを意味しません。
原因は:
- SECURITY DEFINER による実行環境の固定化
- search_path に extensions schema が含まれない
- pgcrypto 関数の解決失敗
これは PostgreSQL の schema 可視性問題であり、Supabase のバグではありません。
📎 適用ケース
本記事は以下の場合に有効です:
- Supabase Auth Trigger エラー
- PostgreSQL SECURITY DEFINER 問題
- pgcrypto 関数が呼び出せない
- Trigger 内で拡張関数が失敗する場合