# Inspecting function environment variables

> Which environment variables SupaHost Edge Functions get, how to confirm a secret is set without revealing it, and why there is no SUPABASE_DB_URL.

Source: https://supahost.app/kb/function-env-vars · Updated 2026-11-11

Secrets on SupaHost are write-only: once saved, their values aren't shown again in the dashboard. To check what a function actually sees, read the environment from inside the function and log **names**, never values.

## What every function gets

SupaHost injects four variables into every function:

| Variable | Value |
|---|---|
| `SUPABASE_URL` | The project URL, e.g. `https://app-one.acme.supahost.space`. If the project has an active custom domain, this is the custom domain. |
| `SUPABASE_ANON_KEY` | The project's public `anon` key |
| `SUPABASE_SERVICE_ROLE_KEY` | The project's `service_role` key. Server-side only; never return it. |
| `SUPABASE_FUNCTION_SLUG` | The slug of the running function |

There is **no `SUPABASE_DB_URL`**. Functions reach the database through supabase-js and the Data API instead of a direct Postgres connection. See [Using the database from a function](/docs/functions/database-access).

Your own secrets come from the Secrets card in *Dashboard → your project → **Functions** tab*. They're shared by all functions in the project.

## Check which variables are set

Deploy a short diagnostic function, call it once, read the result in the Logs card, then delete it.

```ts
// functions/env-check/index.ts
const expected = ['SUPABASE_URL', 'RESEND_API_KEY', 'STRIPE_SECRET_KEY', 'STRIPE_WEBHOOK_SECRET']

Deno.serve(() => {
  const env = Deno.env.toObject()
  for (const name of expected) {
    const value = env[name]
    console.log(name, value ? `set (${value.length} chars)` : 'MISSING')
  }
  console.log('all names:', Object.keys(env).sort().join(', '))
  return Response.json({ ok: true })
})
```

The length helps catch a value pasted with a trailing space or newline, without exposing it. The response body is deliberately empty of details: with **Require JWT** on, anyone holding the public anon key can call a function, so don't return environment information to the caller.

## Common problems

- **A new secret isn't visible yet.** Changes reach functions within about a minute. Wait, then call again.
- **The name doesn't match.** Names are case sensitive: `Resend_Api_Key` and `RESEND_API_KEY` are different. Allowed names start with a letter or underscore and contain letters, digits and underscores, up to 100 characters.
- **You can't create a `SUPABASE_` secret.** That prefix is reserved for the injected variables. Use a different name, such as `APP_SUPABASE_REGION`.
- **The value is wrong.** You can't view it, so overwrite it: save the secret again with the correct value.
- **It works locally but not deployed.** A local `.env` file isn't uploaded. Add each value in the Secrets card.
- **You hit the cap.** A project can hold up to 100 secrets, each up to 10,000 characters. Combine related values into one JSON secret if needed.

## On SupaHost

Secrets are stored in Vault and never shown again after you save them. Only the project owner can add or change them; team members can see the Functions tab read-only. An AI agent over MCP can deploy and read logs, so it can run the diagnostic above for you, but it can't read secret values directly.

## Related

- [Environment variables and secrets](/docs/functions/secrets)
- [Edge Function returns 500](/kb/function-500)
- [Logs and debugging](/docs/functions/logs)
- [Keeping keys safe](/docs/security/api-key-safety)
