fatedier/frp · error
failed to load existing data: %w
Error message
failed to load existing data: %w
What it means
Returned by NewStoreSource when the store file at cfg.Path exists but cannot be read for any reason other than 'file does not exist'. The constructor intentionally treats a missing file as an empty store, so this error means the path exists yet reading it failed (permissions, path is a directory, I/O error). Construction is aborted and no StoreSource is returned.
Source
Thrown at pkg/config/source/store.go:63
const (
storeKindProxy = "proxy"
storeKindVisitor = "visitor"
)
func NewStoreSource(cfg StoreSourceConfig) (*StoreSource, error) {
if cfg.Path == "" {
return nil, fmt.Errorf("path is required")
}
s := &StoreSource{
baseSource: newBaseSource(),
config: cfg,
}
if err := s.loadFromFile(); err != nil {
if !os.IsNotExist(err) {
return nil, fmt.Errorf("failed to load existing data: %w", err)
}
}
return s, nil
}
func (s *StoreSource) loadFromFile() error {
s.mu.Lock()
defer s.mu.Unlock()
return s.loadFromFileUnlocked()
}
func (s *StoreSource) loadFromFileUnlocked() error {
data, err := os.ReadFile(s.config.Path)
if err != nil {
return err
}
View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Check the path and its permissions: ls -la <path> and confirm it is a regular file readable by the account running the process
- Fix ownership/permissions: chown <user> <path> or chmod 644 <path> (or run the process as the owning user)
- If Path points to a directory, change it to a file path such as /var/lib/frpc/store.json
- If the file is stale and disposable, move or delete it so NewStoreSource starts with an empty store (this discards stored proxies/visitors)
- On network filesystems, verify the mount is healthy (mount | grep <dir>, dmesg) before restarting
Example fix
# before: store file created by root, frpc runs as service user Path: /var/lib/frpc/store.json # -rw------- root root # after sudo chown frpc:frpc /var/lib/frpc/store.json sudo chmod 600 /var/lib/frpc/store.json
Defensive patterns
Strategy: try-catch
Validate before calling
func checkStorePathReadable(path string) error {
fi, err := os.Stat(path)
if errors.Is(err, fs.ErrNotExist) {
return nil // missing file is fine: NewStoreSource treats it as empty store
}
if err != nil {
return err
}
if fi.IsDir() {
return fmt.Errorf("%s is a directory, expected a file", path)
}
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("store file not readable: %w", err)
}
f.Close()
return nil
} Try / catch
src, err := source.NewStoreSource(source.StoreSourceConfig{Path: p})
if err != nil {
if os.IsPermission(err) || errors.Is(err, fs.ErrPermission) {
// fix ownership or run as owning user, then exit with actionable message
log.Fatalf("no read access to store file %s: chown/chmod it (current uid=%d)", p, os.Getuid())
}
log.Fatalf("open store: %v", err)
} Prevention
- Pre-create the store file location at deploy time with correct ownership instead of relying on first-run creation by whichever user gets there first
- Never run the process alternately as root and non-root against the same store path
- Keep the store on a local filesystem, not NFS/FUSE, to avoid EIO on read
When it happens
Trigger: Calling NewStoreSource(StoreSourceConfig{Path: p}) where p is a directory, a file without read permission for the current user (e.g. mode 0600 owned by root while frpc runs as nobody), or a file on a failed/unmounted volume. The os.IsNotExist check in NewStoreSource only exempts ENOENT; every other error from loadFromFile lands here.
Common situations: Running the process once as root (or via sudo) so the store file becomes root-owned, then running it as a service user; pointing Path at a directory like /etc/frp instead of a file; an NFS/FUSE mount that dropped and returns EIO on read; SELinux denying access.
Related errors
- failed to create directory: %w
- failed to create temp file: %w
- failed to write temp file: %w
- failed to sync temp file: %w
- failed to close temp file: %w
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/19d90d486cef9b11.
Report an issue: GitHub.