cloudflare/cloudflared · error

get token file owner: %w

Error message

get token file owner: %w

What it means

To reapply restrictive permissions after creating the token file, createTokenFile queries the owner SID from the parsed security descriptor via sd.Owner(). If the SECURITY_DESCRIPTOR has no valid owner or the Win32 lookup fails, the error is wrapped as 'get token file owner'. The owner is then passed to SetSecurityInformation to stamp the same owner on the file.

Source

Thrown at cmd/cloudflared/windows_service.go:180

		windows.FILE_ATTRIBUTE_NORMAL,
		0,
	)

	if err != nil {
		return fmt.Errorf("create token file: %w", err)
	}

	if err := windows.CloseHandle(f); err != nil {
		return fmt.Errorf("close token file: %w", err)
	}

	// As with os.CreateFile / os.OpenFile on Unix, if the file already exists
	// windows.CreateFile will not update the permission information, so we do
	// that explicitly after creating the file.

	owner, _, err := sd.Owner()
	if err != nil {
		return fmt.Errorf("get token file owner: %w", err)
	}

	dacl, _, err := sd.DACL()
	if err != nil {
		return fmt.Errorf("get token file DACL: %w", err)
	}

	// Bitmask indicating which security info we want to set on the file:
	//
	// OWNER_SECURITY_INFORMATION
	//	-> Set file owner
	// DACL_SECURITY_INFORMATION
	// 	-> Set ACEs
	// PROTECTED_DACL_SECURITY_INFORMATION
	//  -> Update DACL to be "protected' such that it cannot inherit entries from its parent
	const securityInfo = windows.OWNER_SECURITY_INFORMATION |
		windows.DACL_SECURITY_INFORMATION |
		windows.PROTECTED_DACL_SECURITY_INFORMATION

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Keep the 'O:BA' owner component in the SDDL string; restore it if it was removed
  2. Validate a custom SDDL string with PowerShell ConvertFrom-SddlString before embedding it
  3. Rebuild from the official source so the original sdString 'O:BAD:P(A;;FA;;;BA)(A;;FA;;;SY)' is used
  4. Apply the latest cloudflared release, which may contain windows-package fixes

Example fix

// before
const sdString = "D:P(A;;FA;;;BA)(A;;FA;;;SY)" // owner component missing
// after
const sdString = "O:BAD:P(A;;FA;;;BA)(A;;FA;;;SY)" // O:BA supplies the owner SID
Defensive patterns

Strategy: try-catch

Validate before calling

# Validate the SDDL parses and has an owner before install
$sddl = 'O:BAD:P(A;;FA;;;BA)(A;;FA;;;SY)'
if (-Not ($sddl -match '^O:')) { Write-Error 'SDDL missing owner component'; exit 1 }
ConvertFrom-SddlString $sddl | Out-Null

Try / catch

if err := installWindowsService(ctx); err != nil {
	if strings.Contains(err.Error(), "get token file owner") {
		log.Error().Msg("security descriptor lost its owner SID; reinstall an official build")
	}
	return err
}

Prevention

When it happens

Trigger: sd.Owner() on the SECURITY_DESCRIPTOR built from the hard-coded SDDL string returns an error — the descriptor carries no owner SID or the SID cannot be resolved.

Common situations: The SDDL constant was edited to drop the O: (owner) field; a malformed owner SID in a customized sdString; an exotic Windows build rejecting the SID component.

Related errors


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