AI-coded apps

    Replit Agent: Error 401 Unauthorized on backend API

    A 2026 view of a Replit Agent app receiving a 401 Unauthorized because a backend secret was set in development but missing from the deployment environment

    A 401 Unauthorized is the backend saying "I do not know who you are," and in a Replit Agent app the cause is almost always an authentication detail rather than a broken API. The classic version is a key or token that works in development but is missing from the deployed environment, so the app authenticates locally and fails once published. The trap is fixing it by hardcoding the key into the client, which turns an auth bug into a security hole. Here is what a 401 means, the common causes, and how to fix it safely.

    Short answer

    A 401 Unauthorized means your backend rejected the request because authentication was missing, wrong, or expired. In a Replit Agent app, the most common causes are an API key or token that is not set in the deployed environment, an auth header that is missing or malformed, an expired token, or, for a backend like Supabase, a request that is anonymous when the endpoint requires an authenticated user under Row Level Security. Fix it by confirming the credential is present and correct in the deployment, attaching the authorization header properly, refreshing expired tokens, and authenticating the user for protected endpoints, without hardcoding any secret into the client.

    What you should know

    • 401 is an auth failure: the backend does not accept who you are.
    • Dev versus deployment is the classic trap: a secret set in dev but not in the deployment.
    • Check the header: a missing or malformed authorization header causes 401.
    • Tokens expire: an expired or unrefreshed token returns 401.
    • Do not hardcode the key to fix it: that swaps an auth bug for a security hole.

    What does a 401 Unauthorized mean?

    That the server could not authenticate the request. A 401 is specifically about identity: the backend received the call but rejected it because the credential needed to prove who you are was absent, incorrect, or no longer valid. It is distinct from a 403 Forbidden, which means you are authenticated but not allowed, and from a 500, which is a server error. So a 401 points you at the authentication layer: the API key, the token, the authorization header, or the login session. In a Replit Agent app, that usually means the credential your code expects to send is not what the backend received, which narrows the search considerably.

    What are the common causes in a Replit Agent app?

    A few authentication issues account for most 401s. The table lists them with the fix.

    CauseWhy it happensFix
    Secret missing in the deploymentThe key is set in dev but not in the deployed environmentAdd the secret to the deployment configuration
    Wrong or rotated keyThe key is incorrect or was rotatedUse the current, correct key
    Missing or malformed auth headerThe Authorization header is absent or lacks the expected formatSend the header in the format the API expects
    Expired tokenA session or token has expiredRefresh the token or re-authenticate
    Anonymous request to a protected endpointSupabase RLS requires an authenticated userSign the user in before calling the endpoint

    The standout is the deployment-versus-development gap: Replit keeps secrets per environment, so a key configured for development but not for the deployment makes the app work while you build and return 401 once it is published. That single mismatch explains a large share of these.

    How do you fix it without hardcoding a key?

    Confirm the credential reaches the deployed backend the right way, and resist the shortcut. First, check that the API key or token is actually set in the deployment's secrets, not just in your development environment, since that gap is the usual cause. Second, verify the request attaches the authorization header in the exact format the API expects, including any Bearer prefix. Third, if you use tokens, confirm they are valid and that your code refreshes them rather than sending an expired one. Fourth, for a Supabase backend, make sure the user is signed in before calling an endpoint protected by Row Level Security, since an anonymous call to a protected table returns 401. Throughout, do not paste a secret key into the client to make the error disappear, since a real secret belongs on your backend, and embedding it trades an auth bug for an exposed credential.

    What to watch out for

    The first trap is the dev-to-deployment secret gap, which makes a 401 appear only after you publish, so check the deployment's secrets first. The second is fixing the 401 by hardcoding a backend secret into the app, which works but ships an extractable credential; keep secrets server-side and authenticate properly instead. The third is confusing 401 with 403, which is a permissions issue, not authentication. A pre-submission scan such as PTKD.com (https://ptkd.com) reads the compiled APK, AAB, or IPA against OWASP MASVS and surfaces hardcoded secrets and endpoints in your build, so you can confirm you did not embed a key while chasing the 401. The auth fix belongs in your configuration and code, not in a secret baked into the client.

    What to take away

    • A 401 Unauthorized means the backend rejected the request because authentication was missing, wrong, or expired.
    • In a Replit Agent app, the top causes are a secret set in dev but not the deployment, a missing or malformed auth header, an expired token, or an anonymous request to a protected endpoint.
    • Fix it by confirming the credential is in the deployment, sending the header correctly, refreshing tokens, and signing the user in for protected endpoints.
    • Never hardcode a backend secret into the client to silence a 401, and use a pre-submission scan such as PTKD.com to confirm none was embedded.
    • #replit-agent
    • #401-unauthorized
    • #api-authentication
    • #backend
    • #supabase
    • #ai-coded-apps
    • #troubleshooting

    Frequently asked questions

    What does a 401 Unauthorized mean?
    It means the server could not authenticate the request: the credential needed to prove who you are was absent, incorrect, or no longer valid. It differs from a 403 Forbidden, which means you are authenticated but not allowed, and from a 500 server error. So a 401 points at the authentication layer, the API key, token, authorization header, or login session, which narrows where to look in a Replit Agent app considerably.
    Why does my Replit app get 401 only after deploying?
    Almost always because the secret is set in your development environment but not in the deployment. Replit keeps secrets per environment, so a key configured for development lets the app work while you build, then the deployed app sends nothing or the wrong value and the backend returns 401. The fix is to add the API key or token to the deployment's secrets configuration, not just the development one, then redeploy and retest.
    How do I fix a 401 on my backend API?
    Confirm the credential reaches the deployed backend correctly. Check the key or token is set in the deployment's secrets, verify the request attaches the authorization header in the exact format the API expects including any Bearer prefix, refresh tokens rather than sending an expired one, and for Supabase sign the user in before calling an endpoint protected by Row Level Security. Work through those in order, since one of them is usually the cause.
    Should I hardcode the API key to fix a 401?
    No. Pasting a backend secret into the client makes the 401 disappear but ships an extractable credential, trading an auth bug for a security hole, since anything in the app bundle can be recovered. Keep real secrets on your backend and have the app authenticate properly, sending a user token or calling your server, which holds the privileged key. The auth fix belongs in your configuration and code, not in a secret embedded in the app.
    Could Row Level Security cause a 401 in my app?
    Yes, indirectly. If your Supabase endpoint is protected and your code calls it without an authenticated user, the request is anonymous and can be rejected, surfacing as an authorization failure. Make sure the user is signed in before calling protected tables, so the request carries a valid user token. This is distinct from a misconfigured key; here the credential exists but the call is not authenticated as the user the policy requires.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free