Skip to main content

Source: ocean/docs/SUPABASE_API_KEY_MIGRATION_ISSUES.md | ✏️ Edit on GitHub

Supabase API Key Migration - Issues and Resolution

Date: July 27, 2025

Summary

During the migration from legacy anon/service_role keys to the new publishable/secret keys, we encountered a critical issue where disabling the legacy keys broke user authentication with "Database error saving new user" errors. This document details the actual problem and solution.

What I Got Wrong

  1. Initial Misdiagnosis: I incorrectly claimed that Supabase's auth service required the anon key to be enabled to function. This was wrong.

  2. Security Claims: I suggested re-enabling the anon key was the only solution, which would have defeated the entire security purpose of the migration.

  3. Lack of Investigation: Instead of properly investigating the error, I made assumptions about Supabase's architecture and limitations.

The Actual Problem

The "Database error saving new user" had nothing to do with the API keys. The real issue was a database trigger we had previously set up:

CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE FUNCTION handle_new_user();

This trigger expected specific metadata (organization, industry, hosting_region) from new user signups. When users tried to sign in via OTP without going through the full signup form, the trigger failed because:

  1. The metadata wasn't provided
  2. The trigger tried to insert NULL values where they weren't expected
  3. The trigger had no error handling, causing the entire user creation to fail

The Solution

We fixed the handle_new_user() function to:

  1. Handle missing metadata gracefully with fallbacks
  2. Add exception handling to prevent trigger failures from breaking user creation
  3. Make provisioning events conditional on having the required data
-- Key changes:
- Added fallback for organization name (uses email domain if metadata missing)
- Made industry and hosting_region truly optional
- Added exception handling that logs errors but doesn't fail user creation
- Made provisioning events conditional on having complete metadata

Key Learnings

  1. "Database error saving new user" is usually about triggers/constraints, not authentication or API keys.

  2. The new publishable/secret keys work fine with the legacy keys disabled - Supabase's documentation is correct.

  3. Always check database triggers when encountering user creation errors.

  4. Don't make assumptions about platform limitations without proper investigation.

Current Status

✅ JWT signing keys successfully rotated ✅ Legacy anon/service_role keys disabled ✅ Using only publishable/secret keys ✅ Authentication fully functional ✅ Security improved with no legacy JWT exposure

Migration Checklist for Others

If you're migrating to the new key system and encounter "Database error saving new user":

  1. Check for triggers on auth.users table - This is the most common cause
  2. Review any custom user tables that sync with auth.users
  3. Ensure metadata expectations match across all user creation paths
  4. Add error handling to any auth-related database functions
  5. Test all authentication flows (signup, signin, OTP, social auth)

What Supabase Could Improve

  1. Better error messages - "Database error saving new user" should indicate if it's trigger-related
  2. Clear documentation that this error is rarely about API keys
  3. Migration guide should mention checking triggers/functions

Apology

I apologize for the confusion and frustration caused by my incorrect diagnosis. You were right to push back and demand a proper investigation. The new API key system does work as advertised - the issue was in our own database configuration.