{"record":{"id":"dfd1d2b121bfefc3","repo":"cloudflare/cloudflared","slug":"get-token-file-owner-w","errorCode":null,"errorMessage":"get token file owner: %w","messagePattern":"get token file owner: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cloudflared/windows_service.go","lineNumber":180,"sourceCode":"\t\twindows.FILE_ATTRIBUTE_NORMAL,\n\t\t0,\n\t)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create token file: %w\", err)\n\t}\n\n\tif err := windows.CloseHandle(f); err != nil {\n\t\treturn fmt.Errorf(\"close token file: %w\", err)\n\t}\n\n\t// As with os.CreateFile / os.OpenFile on Unix, if the file already exists\n\t// windows.CreateFile will not update the permission information, so we do\n\t// that explicitly after creating the file.\n\n\towner, _, err := sd.Owner()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"get token file owner: %w\", err)\n\t}\n\n\tdacl, _, err := sd.DACL()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"get token file DACL: %w\", err)\n\t}\n\n\t// Bitmask indicating which security info we want to set on the file:\n\t//\n\t// OWNER_SECURITY_INFORMATION\n\t//\t-> Set file owner\n\t// DACL_SECURITY_INFORMATION\n\t// \t-> Set ACEs\n\t// PROTECTED_DACL_SECURITY_INFORMATION\n\t//  -> Update DACL to be \"protected' such that it cannot inherit entries from its parent\n\tconst securityInfo = windows.OWNER_SECURITY_INFORMATION |\n\t\twindows.DACL_SECURITY_INFORMATION |\n\t\twindows.PROTECTED_DACL_SECURITY_INFORMATION","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/cmd/cloudflared/windows_service.go#L162-L198","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Keep the 'O:BA' owner component in the SDDL string; restore it if it was removed","Validate a custom SDDL string with PowerShell ConvertFrom-SddlString before embedding it","Rebuild from the official source so the original sdString 'O:BAD:P(A;;FA;;;BA)(A;;FA;;;SY)' is used","Apply the latest cloudflared release, which may contain windows-package fixes"],"exampleFix":"// before\nconst sdString = \"D:P(A;;FA;;;BA)(A;;FA;;;SY)\" // owner component missing\n// after\nconst sdString = \"O:BAD:P(A;;FA;;;BA)(A;;FA;;;SY)\" // O:BA supplies the owner SID","handlingStrategy":"try-catch","validationCode":"# Validate the SDDL parses and has an owner before install\n$sddl = 'O:BAD:P(A;;FA;;;BA)(A;;FA;;;SY)'\nif (-Not ($sddl -match '^O:')) { Write-Error 'SDDL missing owner component'; exit 1 }\nConvertFrom-SddlString $sddl | Out-Null","typeGuard":null,"tryCatchPattern":"if err := installWindowsService(ctx); err != nil {\n\tif strings.Contains(err.Error(), \"get token file owner\") {\n\t\tlog.Error().Msg(\"security descriptor lost its owner SID; reinstall an official build\")\n\t}\n\treturn err\n}","preventionTips":["Never strip the 'O:' component from the SDDL string","Validate custom SDDL strings with ConvertFrom-SddlString","Use official cloudflared releases"],"tags":["windows","sddl","security-descriptor"],"backgroundTag":"security-descriptor-query-failed","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}