wavetermdev/waveterm · error
x-authkey header is invalid
Error message
x-authkey header is invalid
What it means
ValidateIncomingRequest authenticates incoming internal HTTP/WebSocket requests by comparing the x-authkey request header against the in-memory authkey set at startup. If the header value is present but does not match GetAuthKey(), the request is rejected with this error. This protects Wave's internal RPC endpoints from unauthorized local access.
Source
Thrown at pkg/authkey/authkey.go:23
import (
"fmt"
"net/http"
"os"
)
var authkey string
const WaveAuthKeyEnv = "WAVETERM_AUTH_KEY"
const AuthKeyHeader = "X-AuthKey"
func ValidateIncomingRequest(r *http.Request) error {
reqAuthKey := r.Header.Get(AuthKeyHeader)
if reqAuthKey == "" {
return fmt.Errorf("no x-authkey header")
}
if reqAuthKey != GetAuthKey() {
return fmt.Errorf("x-authkey header is invalid")
}
return nil
}
func SetAuthKeyFromEnv() error {
authkey = os.Getenv(WaveAuthKeyEnv)
if authkey == "" {
return fmt.Errorf("no auth key found in environment variables")
}
os.Unsetenv(WaveAuthKeyEnv)
return nil
}
func GetAuthKey() string {
return authkey
}
View on GitHub (pinned to a4447c1563)
Solutions
- Set the same WAVE_AUTHKEY environment variable for both the server process and the client making the request, then restart both
- Verify the server actually accepted the key (SetAuthKeyFromEnv succeeded) and re-read it via GetAuthKey()
- Kill duplicate Wave server instances that may be listening with an old key
- If the header is set by tooling (proxy, curl script), update the injected header value to match the current key
Example fix
// before curl -H 'x-authkey: oldkey' http://localhost:2665/awldollar // after export WAVE_AUTHKEY=currentkey curl -H "x-authkey: $WAVE_AUTHKEY" http://localhost:2665/awldollar
Defensive patterns
Strategy: validation
Validate before calling
func hasValidAuthKey(r *http.Request, expected string) bool {
return r.Header.Get("x-authkey") != "" && r.Header.Get("x-authkey") == expected
} Type guard
func hasAuthHeader(r *http.Request) bool { return r.Header.Get("x-authkey") != "" } Try / catch
if err := authkey.ValidateIncomingRequest(req); err != nil {
if strings.Contains(err.Error(), "invalid") { /* key mismatch: refresh key and retry once */ }
return err
} Prevention
- Always source WAVE_AUTHKEY from the same environment for server and clients
- Restart paired processes together after key changes
- Log (hashed) key comparisons when debugging auth failures
- Avoid hardcoding auth keys in scripts
When it happens
Trigger: Any HTTP/WS request (HandleWsInternal or anonymous handler) whose x-authkey header holds a stale, wrong, or mismatched value relative to WAVE_AUTHKEY set for the running server process.
Common situations: A client (wsh, extension, older frontend) launched with a different WAVE_AUTHKEY value than the server; multiple Wave instances running with different keys; a hardcoded or cached key after the server restarted and picked up a new key.
Related errors
- missing zone file info for ${zoneId}:${fileName}
- call ${methodName} failed: ${resp.status} ${resp.statusText}
- Failed to fetch config: ${configResponse.statusText}
- Failed to fetch data: ${dataResponse.statusText}
- HTTP ${response.status}: ${response.statusText}
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/cdc585405f03f388.
Report an issue: GitHub.