Skip to content

fix(windows): use %ProgramFiles% and %ProgramData% for default configuration variables#2203

Open
tsomerve wants to merge 1 commit intonewrelic:masterfrom
tsomerve:tsomervell-win-fix
Open

fix(windows): use %ProgramFiles% and %ProgramData% for default configuration variables#2203
tsomerve wants to merge 1 commit intonewrelic:masterfrom
tsomerve:tsomervell-win-fix

Conversation

@tsomerve
Copy link
Copy Markdown

Summary

Fix Windows zip installation on hosts where %ProgramFiles% or %ProgramData% are
remapped to a non-system drive (e.g. E: on FedRAMP-restricted environments). Secondary
services — fluent-bit/logging and nri-winservices — fail to start because the agent
resolves their paths to C: instead of the actual installation drive.

Root cause

Two independent bugs share the same class of mistake: using a hardcoded drive letter
instead of the appropriate Windows environment variable.

Bug 1 — pkg/config/config_windows.go

defaultAgentDir is built by concatenating %SystemDrive% with the string
"Program Files\New Relic\newrelic-infra". When %ProgramFiles% is remapped to E:
but %SystemDrive% is still C:, every path derived from defaultAgentDir resolves to
C: — including the fluent-bit exe path, safe_bin_dir, and config_dir.

// before
sysDrive := os.Getenv("SystemDrive") + string(filepath.Separator)
defaultAgentDir = filepath.Join(sysDrive, installationSubdir)

// after
defaultAgentDir = filepath.Join(os.Getenv("ProgramFiles"), "New Relic", "newrelic-infra")

Bug 2 — cmd/newrelic-infra/initialize/initialize_windows.go

agentTemporaryFolder is hardcoded to C:\ProgramData\New Relic\newrelic-infra\tmp.
emptyTemporaryFolder() only creates the temp directory when
cfg.AgentTempDir == agentTemporaryFolder. When %ProgramData% is remapped to E:,
cfg.AgentTempDir resolves to E:\ProgramData\... and the condition is always false —
the temp directory is never created on first run, blocking fluent-bit config generation.

// before (const)
agentTemporaryFolder = "C:\\ProgramData\\New Relic\\newrelic-infra\\tmp"

// after (var, derived at startup)
var agentTemporaryFolder = filepath.Join(os.Getenv("ProgramData"), "New Relic", "newrelic-infra", "tmp")

Files changed

File Change
pkg/config/config_windows.go Use %ProgramFiles% for defaultAgentDir; remove unused installationSubdir const
cmd/newrelic-infra/initialize/initialize_windows.go Replace hardcoded C:\ProgramData constant with %ProgramData% env var; add path/filepath import

Testing

Reproduced on a Windows Server 2019 Azure VM with %ProgramFiles% and %ProgramData%
remapped to E: and the agent installed via zip. Confirmed:

  • Before fix: agent starts, fluent-bit reports "exe not found" at
    C:\Program Files\...\logging\fluent-bit.exe (wrong drive)
  • After fix (simulated via config): fluent-bit found at
    E:\Program Files\...\logging\fluent-bit.exe, progresses to full initialization

Startup log showing the bug (agent_dir on C: despite agent installed on E:):

agent_dir="C:\\Program Files\\New Relic\\newrelic-infra"
Fluent Bit exe not found. fbExePath="C:\\Program Files\\New Relic\\newrelic-infra\\newrelic-integrations\\logging\\fluent-bit.exe"

Workaround for existing customers

Until this fix ships, customers can set all three in newrelic-infra.yml (note:
double-escaped backslashes are required in YAML double-quoted strings):

agent_dir:    "E:\\Program Files\\New Relic\\newrelic-infra"
config_dir:   "E:\\Program Files\\New Relic\\newrelic-infra"
safe_bin_dir: "E:\\Program Files\\New Relic\\newrelic-infra"

This does not work around Bug 2. The temp directory must also be pre-created manually:

New-Item -ItemType Directory -Force "E:\ProgramData\New Relic\newrelic-infra\tmp"

…lt paths

Replace hardcoded C: drive references in Windows path initialization with the
appropriate environment variables.

Bug 1 (config_windows.go): defaultAgentDir was built from %SystemDrive% +
"Program Files" instead of %ProgramFiles%, causing all derived paths
(agent_dir, safe_bin_dir, config_dir, logging_home_dir, integration binary
search paths) to resolve to C: when %ProgramFiles% is remapped to another
drive.

Bug 2 (initialize_windows.go): agentTemporaryFolder was hardcoded to
C:\ProgramData\..., causing emptyTemporaryFolder() to never create the temp
directory when %ProgramData% is on a non-C: drive, since the guard condition
cfg.AgentTempDir == agentTemporaryFolder is always false.

Affects zip installations on hosts where %ProgramFiles% or %ProgramData% are
remapped to a non-system drive (e.g. FedRAMP-restricted environments).
Secondary services (fluent-bit, nri-winservices) fail to start as a result.
@tsomerve tsomerve requested a review from a team as a code owner March 10, 2026 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant