{"record":{"id":"cbed9e2715fb131e","repo":"router-for-me/CLIProxyAPI","slug":"plugin-store-resolved-auth-header-value-is-empty","errorCode":null,"errorMessage":"plugin store resolved auth header value is empty","messagePattern":"plugin store resolved auth header value is empty","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/pluginstore/auth.go","lineNumber":301,"sourceCode":"\tcase AuthTypeBasic:\n\t\tif len(item.Username) == 0 || len(item.Password) == 0 {\n\t\t\treturn false, fmt.Errorf(\"plugin store resolved basic auth is incomplete\")\n\t\t}\n\t\tcredential := make([]byte, 0, len(item.Username)+1+len(item.Password))\n\t\tcredential = append(credential, item.Username...)\n\t\tcredential = append(credential, ':')\n\t\tcredential = append(credential, item.Password...)\n\t\tencoded := base64.StdEncoding.EncodeToString(credential)\n\t\tfor index := range credential {\n\t\t\tcredential[index] = 0\n\t\t}\n\t\theaders.Set(\"Authorization\", \"Basic \"+encoded)\n\tcase AuthTypeHeader:\n\t\tif strings.TrimSpace(item.HeaderName) == \"\" {\n\t\t\treturn false, fmt.Errorf(\"plugin store resolved auth missing header-name\")\n\t\t}\n\t\tif len(item.HeaderValue) == 0 {\n\t\t\treturn false, fmt.Errorf(\"plugin store resolved auth header value is empty\")\n\t\t}\n\t\theaders.Set(item.HeaderName, string(item.HeaderValue))\n\tdefault:\n\t\treturn false, fmt.Errorf(\"unsupported plugin store resolved auth type %q\", item.Type)\n\t}\n\treturn true, nil\n}\n\nfunc validatePluginStoreRequestURL(auth []AuthConfig, requestURL string, kind string) error {\n\tparsed, errParse := url.Parse(strings.TrimSpace(requestURL))\n\tif errParse != nil || parsed.Scheme == \"\" || parsed.Host == \"\" {\n\t\treturn fmt.Errorf(\"invalid plugin store url\")\n\t}\n\tif parsed.User != nil {\n\t\treturn fmt.Errorf(\"plugin store url must not contain credentials\")\n\t}\n\tif hasSensitiveQueryParameter(parsed) {\n\t\treturn fmt.Errorf(\"plugin store url contains sensitive query parameter\")","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/auth.go#L283-L319","documentation":"Thrown while applying a header-type plugin-store auth rule: the header value resolved to an empty byte slice. internal/pluginstore/auth.go checks len(item.HeaderValue) == 0 before calling headers.Set, because sending a named header with an empty value would produce a guaranteed-401 request. The value usually comes from an environment variable (header-value-env), so an unset or blank env var is the typical root cause.","triggerScenarios":"A header-type auth rule matches the request URL and kind, but the env var named by header-value-env is unset, empty, or whitespace that was trimmed to zero bytes during resolution.","commonSituations":"Env var not exported in the shell/service unit that runs CLIProxyAPI; .env file missing the key; secret rotated to an empty value; deploy environment (container/systemd) differs from the developer shell where the variable exists.","solutions":["Set the referenced env var to the real token value in the environment that runs the server (export it, add it to .env, or the systemd/docker env)","Confirm the header-value-env name in config.yaml matches the variable name exactly (case-sensitive)","Check for whitespace-only values — the resolver trims and yields an empty Secret","Restart the process so the env change is picked up"],"exampleFix":"# before (.env)\n# PLUGIN_API_KEY=  (empty)\n\n# after (.env)\nPLUGIN_API_KEY=actual-secret-value","handlingStrategy":"validation","validationCode":"if strings.EqualFold(strings.TrimSpace(rule.Type), \"header\") {\n    v := strings.TrimSpace(os.Getenv(rule.HeaderValueEnv))\n    if v == \"\" {\n        return fmt.Errorf(\"env %s unset; will fail auth resolution\", rule.HeaderValueEnv)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Fail fast at boot: resolve every configured *-env secret during startup and abort if any is empty","Run CLIProxyAPI under a process manager that fails when required env vars are missing (systemd EnvironmentFile with strict mode, docker --env-file plus a preflight)"],"tags":["auth","env","plugin-store","config"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}