cloudflare/cloudflared · error
locate config dir: %w
Error message
locate config dir: %w
What it means
installWindowsService needs the cloudflared config directory under %PROGRAMDATA% before it can create the service and write the token file. It calls getConfigDir and, on failure, re-wraps the underlying error ('could not find program data directory...') with 'locate config dir'. This is a wrapper — the root cause is always the missing PROGRAMDATA environment variable from error 188.
Source
Thrown at cmd/cloudflared/windows_service.go:334
if err == nil {
s.Close()
return errors.New(serviceAlreadyExistsWarn(windowsServiceName))
}
var extraArgs []string
if c.NArg() > 0 {
// The service has been installed using a token e.g.,
// $ cloudflared service install <token>
//
// Write the token file to a config directory so we can start the
// service with --token-file.
// Don't use :=, if we did so we would create a new err variable and
// shadow the outer one, causing the defer below to not have access to
// the outer err
var configDir string
configDir, err = getConfigDir()
if err != nil {
return fmt.Errorf("locate config dir: %w", err)
}
// Remove token file if service install fails any point onwards from here
defer func() {
if err != nil {
removeTokenFile(configDir, zeroLogger)
}
}()
if err = writeTokenToConfigDir(c, configDir); err != nil {
return fmt.Errorf("write token to configuration directory at %s: %w", configDir, err)
}
extraArgs = buildArgsForTokenFile(configDir)
}
config := mgr.Config{StartType: mgr.StartAutomatic, DisplayName: windowsServiceDescription}
s, err = m.CreateService(windowsServiceName, exepath, config, extraArgs...)View on GitHub (pinned to 2253eeeb25)
Solutions
- Set/restore the system PROGRAMDATA environment variable (default C:\ProgramData)
- Run the install from a standard elevated cmd/PowerShell window
- Prefix the command with the variable: set PROGRAMDATA=C:\ProgramData && cloudflared service install <args>
- Check the wrapped inner message to confirm the root cause is the missing PROGRAMDATA var
Example fix
# before $env:PROGRAMDATA = $null; cloudflared service install <token> # after (PowerShell) $env:PROGRAMDATA = "C:\ProgramData" cloudflared service install <token>
Defensive patterns
Strategy: validation
Validate before calling
# PowerShell: verify env before invoking install
if (-Not $env:PROGRAMDATA) { $env:PROGRAMDATA = 'C:\ProgramData' }
if (-Not (Test-Path $env:PROGRAMDATA)) { throw "PROGRAMDATA path $env:PROGRAMDATA does not exist" } Try / catch
if err := installWindowsService(ctx); err != nil {
if strings.Contains(err.Error(), "locate config dir") {
os.Setenv("PROGRAMDATA", `C:\ProgramData`) // or re-exec from a normal shell
return installWindowsService(ctx)
}
return err
} Prevention
- Set PROGRAMDATA explicitly when automating installs
- Use the standard elevated installer flow rather than bespoke runners
- Confirm the variable with `echo %PROGRAMDATA%` before invoking cloudflared service install
- Keep system environment variables uncorrupted (check via System Properties > Environment Variables)
When it happens
Trigger: Any call to `cloudflared service install` in an environment where PROGRAMDATA is unset, causing getConfigDir to fail and be wrapped here.
Common situations: Same as error 188: stripped environments from custom service runners, scheduled tasks, containers, or corrupted environment variables when installing the cloudflared Windows service.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- could not find program data directory, %s env var must be se
- cloudflared service is already installed at ${service}; if y
- Error during update : %s;
- create token security descriptor: %w
- convert path to UTF-16: %w
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/463321ca2bbb381e.
Report an issue: GitHub.