Skip to content
Latchkey

LaunchDarkly 401 "invalid SDK key" in CI

The LaunchDarkly SDK authenticated against the streaming or polling endpoint and was rejected with HTTP 401. The service is reachable; the SDK key you passed is invalid, empty, or belongs to a different environment. The SDK stops fetching flags and serves fallback defaults.

What this error means

LaunchDarkly logs "Error on stream connection: HTTP error 401 (invalid SDK key), giving up permanently" or "Received HTTP error 401 ... invalid SDK key". Every variation call then returns the code default.

LaunchDarkly
[LaunchDarkly] ERROR: Error on stream connection: HTTP error 401 (invalid SDK key)
for URL https://stream.launchdarkly.com/all, giving up permanently

Diagnose it: did the report reach the service?

Coverage and quality integrations fail in two distinct places: the report was never produced, or it was produced and the upload was rejected. Establish which before touching tokens.

Terminal
# 1. does the report exist and is it non-empty?
ls -la coverage/ && head -5 coverage/lcov.info

# 2. does it reference paths the service can map to the repo?
grep "^SF:" coverage/lcov.info | head -5

# 3. did the upload actually succeed, or just not fail the step?
# most uploaders exit 0 on a rejected upload unless told otherwise

Common causes

The server-side SDK key is missing or empty in CI

The secret was never exposed to the job, so the SDK client is constructed with an empty string and LaunchDarkly rejects it with 401.

A mobile or client-side ID was used instead of the server SDK key

Server SDKs need the "SDK key"; passing the client-side ID or a mobile key returns 401 (invalid SDK key).

How to fix it

Inject the correct server-side SDK key from a secret

  1. Copy the environment's server-side SDK key from Account settings, Projects in LaunchDarkly.
  2. Store it as a CI secret and expose it to the step as an env var.
  3. Confirm you are using the SDK key, not the client-side ID or mobile key.
.github/workflows/ci.yml
env:
  LAUNCHDARKLY_SDK_KEY: ${{ secrets.LAUNCHDARKLY_SDK_KEY }}

Verify the key matches the target environment

Each LaunchDarkly environment (test, staging, production) has its own SDK key. A 401 will not clear on retry: confirm the key belongs to the environment your CI run targets.

How to prevent it

  • Keep the LaunchDarkly SDK key in CI secrets, never committed.
  • Use a dedicated test environment key for CI so production flags stay isolated.
  • Fail the job early if the key env var is empty rather than silently serving defaults.

Frequently asked questions

What causes LaunchDarkly 401 "invalid SDK key" in CI?
There are 2 common causes: the server-side sdk key is missing or empty in ci and a mobile or client-side id was used instead of the server sdk key. The secret was never exposed to the job, so the SDK client is constructed with an empty string and LaunchDarkly rejects it with 401.
How do I fix LaunchDarkly 401 "invalid SDK key" in CI?
There are 2 fixes depending on which cause you have: inject the correct server-side sdk key from a secret and verify the key matches the target environment. Work through them in order, since the first is the most common.
What does LaunchDarkly 401 "invalid SDK key" in CI actually mean?
LaunchDarkly logs "Error on stream connection: HTTP error 401 (invalid SDK key), giving up permanently" or "Received HTTP error 401 ...
How do I stop LaunchDarkly 401 "invalid SDK key" in CI happening again?
Keep the LaunchDarkly SDK key in CI secrets, never committed. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card