{"record":{"id":"eede16605b94e6a1","repo":"jaegertracing/jaeger","slug":"failed-to-read-token-file-w","errorCode":null,"errorMessage":"failed to read token file: %w","messagePattern":"failed to read token file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/tokenloader.go","lineNumber":42,"sourceCode":"\t\tlastRead    time.Time\n\t)\n\n\treturn func() (string, error) {\n\t\tmu.Lock()\n\t\tdefer mu.Unlock()\n\n\t\tnow := timeFn()\n\n\t\t// Special case: interval = 0 means \"never reload after first load\"\n\t\t// Otherwise reload only if `interval` time has passed since last load.\n\t\tif !lastRead.IsZero() && (interval == 0 || now.Sub(lastRead) < interval) {\n\t\t\treturn cachedToken, nil\n\t\t}\n\n\t\t// Read from file\n\t\tb, err := os.ReadFile(filepath.Clean(path))\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to read token file: %w\", err)\n\t\t}\n\n\t\tcachedToken = strings.TrimRight(string(b), \"\\r\\n\")\n\t\tlastRead = now\n\t\treturn cachedToken, nil\n\t}\n}\n\n// TokenProvider creates a token provider that handles file loading and error handling consistently.\nfunc TokenProvider(path string, interval time.Duration, logger *zap.Logger) (func() string, error) {\n\treturn TokenProviderWithTime(path, interval, logger, time.Now) // Use real time.Now in production\n}\n\n// TokenProviderWithTime creates a token provider with injectable time (for testing)\nfunc TokenProviderWithTime(path string, interval time.Duration, logger *zap.Logger, timeFn func() time.Time) (func() string, error) {\n\tloader := cachedFileTokenLoader(path, interval, timeFn)\n\n\t// current token load","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/auth/tokenloader.go#L24-L60","documentation":"The cached file token loader in internal/auth/tokenloader.go:42 wraps os.ReadFile errors with this message when it cannot read the bearer-token file at the given path. The loader caches the token for a configurable interval and re-reads the file when the interval expires, so this error can occur on the first read and on later reloads. On the initial load it is further wrapped as \"failed to get token from file\" by TokenProviderWithTime; on later reloads it is only logged as a warning and the last cached token is used.","triggerScenarios":"os.ReadFile(filepath.Clean(path)) failing because the file does not exist (ENOENT), the process lacks read permission (EACCES), the path is a directory, or — on a reload after the cache interval elapsed — the file was deleted or rotated away between reads.","commonSituations":"Kubernetes secret mounted at a different path than configured, or the volume not yet populated at startup; credential rotation that briefly removes the file; running locally without the token file the deployment config expects; wrong relative vs absolute path.","solutions":["Verify the configured path exists and is readable by the process (ls -l <path> as the same user); fix the path or the secret mount","If the file is rotated, rotate atomically (write new file, rename into place) instead of removing then creating it","Set interval=0 to disable reloading so the loader never re-reads after the first successful load","Recreate the token file and restart the process if the initial load failed, since TokenProvider construction aborts on it"],"exampleFix":"// before\n// token file path: /var/run/secrets/token  (file absent)\n// after\n// $ ls -l /var/run/secrets/token\n// -r-------- 1 app app 215 ... /var/run/secrets/token\n// or set interval to 0 to never reload after the first successful read","handlingStrategy":"fallback","validationCode":"// check readability before relying on the provider\nif info, err := os.Stat(tokenPath); err != nil {\n\treturn fmt.Errorf(\"token file %s not accessible: %w\", tokenPath, err)\n} else if info.IsDir() {\n\treturn fmt.Errorf(\"token path %s is a directory\", tokenPath)\n}","typeGuard":null,"tryCatchPattern":"tokenFn, err := auth.TokenProvider(tokenPath, interval, logger)\nif err != nil {\n\t// on reload failures the provider itself falls back to the last cached token,\n\t// so only construction errors need handling here\n\tlogger.Error(\"token auth unavailable\", zap.Error(err))\n\treturn err\n}","preventionTips":["Mount secrets with atomic rotation (symlink swap, e.g. Kubernetes projected volumes) so the file is never absent","Set interval=0 to disable reloads when the token never rotates","Verify secret mount paths in deployment manifests match the configured token path","Check file permissions are readable by the service user (0400/0444 owned by the app)"],"tags":["auth","filesystem","token","file-io"],"backgroundTag":"token-file-unreadable","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}