Code Beginner easy · 4 min

AuthenticationError: cause and fix

What you will learn
AuthenticationError happens when LangChain can't authenticate with an LLM provider: fix it by setting your API key correctly as an environment variable or in the client constructor.

Why this matters

You'll hit this error on your first attempt to call an LLM. Understanding the root cause and the three ways to fix it saves you 20 minutes of debugging and teaches you LangChain's authentication design.

Skip if: When you're testing locally with a mock LLM or using a fully open-source model running on your own hardware that requires no authentication (like Ollama). In that case, credentials are irrelevant.

Explanation

What it is: An AuthenticationError is raised when LangChain tries to call an LLM provider (OpenAI, Anthropic, etc.) but cannot present valid credentials. This is a permissions failure, not a configuration mistake.

How it works mechanically: When you instantiate a language model like ChatOpenAI(), the client looks for credentials in three places in this order: (1) explicit constructor parameters, (2) environment variables (e.g., OPENAI_API_KEY), (3) default credential chains (like AWS IAM or GCP service accounts). If none contain a valid key, the API request fails at the remote server and raises AuthenticationError.

When to address it: Always set credentials before you instantiate any model. The error won't surface until you call .invoke() or .stream(), so you'll discover it at runtime, not import time.

Analogy

It's like trying to use someone else's credit card without their permission. The card reader (the API) rejects it at the point of transaction, not when you pull the card out of your wallet.

Code

Illustrative only - not runnable without a valid API key
python
import os
from langchain_openai import ChatOpenAI

# Attempt 1: No credentials set — this will raise AuthenticationError
try:
    if "OPENAI_API_KEY" in os.environ:
        del os.environ["OPENAI_API_KEY"]
    
    llm = ChatOpenAI(model="gpt-4o-mini")
    result = llm.invoke("Hello")
    print(result)
except Exception as e:
    print(f"Error type: {type(e).__name__}")
    print(f"Error message: {str(e)[:100]}")

print("\n---\n")

# Fix 1: Set environment variable before instantiating
os.environ["OPENAI_API_KEY"] = "sk-proj-your-actual-key-here"
llm = ChatOpenAI(model="gpt-4o-mini")
print(f"Fix 1 (env var): Client created successfully")
print(f"Model in use: {llm.model_name}")

print("\n---\n")

# Fix 2: Pass credentials directly in constructor
llm_direct = ChatOpenAI(
    model="gpt-4o-mini",
    api_key="sk-proj-your-actual-key-here"
)
print(f"Fix 2 (direct param): Client created successfully")
print(f"Model in use: {llm_direct.model_name}")

print("\n---\n")

# Fix 3: Use environment variable explicitly (identical to Fix 1, shown for clarity)
api_key_from_env = os.environ.get("OPENAI_API_KEY")
if api_key_from_env:
    llm_env = ChatOpenAI(model="gpt-4o-mini")
    print(f"Fix 3 (explicit env check): Client created successfully")
    print(f"Key found in environment: {len(api_key_from_env) > 0}")
Output
Error type: AuthenticationError
Error message: 401 Client Error: Unauthorized for url: https://api.openai.com/v1/chat/completions

---

Fix 1 (env var): Client created successfully
Model in use: gpt-4o-mini

---

Fix 2 (direct param): Client created successfully
Model in use: gpt-4o-mini

---

Fix 3 (explicit env check): Client created successfully
Key found in environment: True

What just happened?

The code first attempts to invoke an LLM without credentials (after removing any existing OPENAI_API_KEY from the environment), triggering an <code>AuthenticationError</code> with a 401 Unauthorized response. Then it demonstrates three working patterns: setting the environment variable, passing the key directly to the constructor, and reading from the environment before client creation. All three succeed at client instantiation because valid (though fake) keys are now present.

Common gotcha

Developers often assume the error happens at ChatOpenAI() instantiation time, but it actually happens when you call .invoke() or .stream(). You can create a client with a missing key: the error only surfaces on the first API call. This delays error discovery and can mask the real issue if you're not watching the right line.

Error recovery

AuthenticationError
Root cause: API key is missing, invalid, or has expired. Fix: (1) Verify key exists in <code>OPENAI_API_KEY</code> environment variable with <code>echo $OPENAI_API_KEY</code> (macOS/Linux) or <code>echo %OPENAI_API_KEY%</code> (Windows). (2) If blank, set it: <code>export OPENAI_API_KEY='sk-proj-...'</code>. (3) If the key is real but still fails, log into your OpenAI dashboard and regenerate the key (old ones may be revoked).
ModuleNotFoundError: No module named 'langchain_openai'
The provider-specific package is missing. Fix: <code>pip install langchain-openai</code>. langchain 1.2.x does not bundle provider clients; install them separately.

Experienced dev note

In production, never pass API keys as constructor parameters or hardcode them in source. Always use environment variables or a secrets manager (like HashiCorp Vault, AWS Secrets Manager, or Python's dotenv for local dev). Constructor params are tempting because they're explicit, but they leak credentials into logs, stack traces, and git history. Environment variables are the LangChain convention: respect it. Also: test with a cheapest-possible model (like gpt-4o-mini) in development to avoid surprise bills from accidental script loops.

Check your understanding

If you set OPENAI_API_KEY in your shell environment, why does ChatOpenAI().invoke("hello") still raise AuthenticationError when you run a Python script?

Show answer hint

The answer requires understanding that environment variables set in the shell are inherited by the Python process only if the Python process is a child of that shell session. If Python was started from a different shell or IDE that doesn't inherit the parent environment, the key won't be visible. Also, the error happens on the API call, not instantiation, so the timing of when you set the key matters relative to when you call the method.

VERSION In langchain < 0.1.0, you imported from langchain.chat_models import ChatOpenAI. Since langchain 0.1.0, the correct import is from langchain_openai import ChatOpenAI (a separate package). Using the old import pattern in langchain 1.2.x will raise ImportError, not AuthenticationError, but misdiagnosis is common.
NEXT

Now that you can authenticate, learn how to structure prompts with <code>ChatPromptTemplate</code> to pass validated input into your LLM reliably.

Community Notes

No notes yetBe the first to share a version-specific fix or tip.