cloudflare/cloudflared · error · ErrKeyNotFound

parsing os information: %w, key=%s

Error message

parsing os information: %w, key=%s

What it means

ParseWinOperatingSystemInfo parses Windows OS information from a key/value mapping (e.g. `wmic` or registry query output) and requires both the architecture key and the OS system key to be present. When either key is absent from the parsed pairs it returns ErrKeyNotFound wrapped in this message with the offending key name, so the Windows OS info cannot be assembled.

Source

Thrown at diagnostic/system_collector_utils.go:182

	output string,
	architectureKey string,
	osSystemKey string,
	osVersionKey string,
	osReleaseKey string,
	nameKey string,
) (*OsInfo, error) {
	identity := func(s string) (string, error) { return s, nil }

	keys := []string{architectureKey, osSystemKey, osVersionKey, osReleaseKey, nameKey}
	pairs := findColonSeparatedPairs(
		output,
		keys,
		identity,
	)

	architecture, exists := pairs[architectureKey]
	if !exists {
		return nil, fmt.Errorf("parsing os information: %w, key=%s", ErrKeyNotFound, architectureKey)
	}

	osSystem, exists := pairs[osSystemKey]
	if !exists {
		return nil, fmt.Errorf("parsing os information: %w, key=%s", ErrKeyNotFound, osSystemKey)
	}

	osVersion, exists := pairs[osVersionKey]
	if !exists {
		return nil, fmt.Errorf("parsing os information: %w, key=%s", ErrKeyNotFound, osVersionKey)
	}

	osRelease, exists := pairs[osReleaseKey]
	if !exists {
		return nil, fmt.Errorf("parsing os information: %w, key=%s", ErrKeyNotFound, osReleaseKey)
	}

	name, exists := pairs[nameKey]

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Log/inspect the parsed `pairs` map to see which keys actually came back and compare against architectureKey/osSystemKey.
  2. Replace deprecated wmic-based collection with PowerShell (`Get-CimInstance Win32_OperatingSystem`) or direct registry reads that reliably expose the expected values.
  3. Run the collector with sufficient privileges so WMI/registry queries return complete data.
  4. Handle locale differences: query values by stable property/registry names (not localized display strings) or set the query to invariant culture/English output.

Example fix

// before
pairs, err := buildKV(output, keys, identity)
info, err := diagnostic.ParseWinOperatingSystemInfo(output)
// after
pairs, err := buildKV(output, keys, identity)
if err != nil {
	return fmt.Errorf("os info query failed: %w", err)
}
for _, k := range []string{architectureKey, osSystemKey} {
	if _, ok := pairs[k]; !ok {
		return fmt.Errorf("missing os info key %q in: %v", k, pairs)
	}
}
info, err := diagnostic.ParseWinOperatingSystemInfo(output)
Defensive patterns

Strategy: validation

Validate before calling

func validateOsInfoPairs(pairs map[string]string, required ...string) error {
	for _, k := range required {
		if _, ok := pairs[k]; !ok {
			return fmt.Errorf("missing required os info key: %s", k)
		}
	}
	return nil
}

Try / catch

info, err := diagnostic.ParseWinOperatingSystemInfo(output)
var target error = diagnostic.ErrKeyNotFound
if errors.Is(err, target) {
	log.Warn().Msg("Windows OS info incomplete; skipping OS diagnostics")
} else if err != nil {
	return fmt.Errorf("windows os info parse failed: %w", err)
}

Prevention

When it happens

Trigger: Calling ParseWinOperatingSystemInfo (directly or via collectOSInformation on Windows) when the underlying command/query output lacks `architectureKey` or `osSystemKey` — e.g. wmic/registry output in a different language, a stripped-down Windows image, or output redirection failing so pairs is empty or partial.

Common situations: Non-English Windows locales renaming Caption/OSArchitecture values, wmic being deprecated/removed on newer Windows builds so the query returns nothing, running with insufficient privileges to read the registry/WMI, or parsing output whose format changed between Windows versions.

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/36ff1fe6dab252d1. Report an issue: GitHub.