From 902869af151e3237c663827b4d457de27485130a Mon Sep 17 00:00:00 2001 From: chrislu Date: Thu, 4 Dec 2025 14:54:26 -0800 Subject: [PATCH] fix: Admin UI user creation fails before filer discovery (#7624) The credential manager's filer address function was not configured quickly enough after admin server startup, causing 'filer address function not configured' errors when users tried to create users immediately. Changes: - Use exponential backoff (200ms -> 5s) instead of fixed 5s polling for faster filer discovery on startup - Improve error messages to be more user-friendly and actionable Fixes #7624 --- weed/admin/dash/admin_server.go | 14 +++++++++++--- weed/credential/filer_etc/filer_etc_store.go | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/weed/admin/dash/admin_server.go b/weed/admin/dash/admin_server.go index 4ce357502..60b8b1999 100644 --- a/weed/admin/dash/admin_server.go +++ b/weed/admin/dash/admin_server.go @@ -106,7 +106,10 @@ func NewAdminServer(masters string, templateFS http.FileSystem, dataDir string) SetFilerAddressFunc(func() pb.ServerAddress, grpc.DialOption) }); ok { // Set up a goroutine to configure filer address function once we discover filers + // Use aggressive initial retries with exponential backoff for faster startup go func() { + retryInterval := 200 * time.Millisecond // Start with fast retries + maxInterval := 5 * time.Second for { filerAddr := server.GetFilerAddress() if filerAddr != "" { @@ -114,11 +117,16 @@ func NewAdminServer(masters string, templateFS http.FileSystem, dataDir string) filerFuncSetter.SetFilerAddressFunc(func() pb.ServerAddress { return pb.ServerAddress(server.GetFilerAddress()) }, server.grpcDialOption) - glog.V(1).Infof("Set filer address function for credential manager: %s", filerAddr) + glog.V(0).Infof("Credential manager configured with filer: %s", filerAddr) break } - glog.V(1).Infof("Waiting for filer discovery for credential manager...") - time.Sleep(5 * time.Second) + glog.V(1).Infof("Waiting for filer discovery for credential manager (retry in %v)...", retryInterval) + time.Sleep(retryInterval) + // Exponential backoff up to maxInterval + retryInterval = retryInterval * 2 + if retryInterval > maxInterval { + retryInterval = maxInterval + } } }() } diff --git a/weed/credential/filer_etc/filer_etc_store.go b/weed/credential/filer_etc/filer_etc_store.go index b181a55f0..e174b5ef4 100644 --- a/weed/credential/filer_etc/filer_etc_store.go +++ b/weed/credential/filer_etc/filer_etc_store.go @@ -58,7 +58,7 @@ func (store *FilerEtcStore) withFilerClient(fn func(client filer_pb.SeaweedFiler store.mu.RLock() if store.filerAddressFunc == nil { store.mu.RUnlock() - return fmt.Errorf("filer_etc: filer address function not configured") + return fmt.Errorf("filer_etc: filer not yet available - please wait for filer discovery to complete and try again") } filerAddress := store.filerAddressFunc() @@ -66,7 +66,7 @@ func (store *FilerEtcStore) withFilerClient(fn func(client filer_pb.SeaweedFiler store.mu.RUnlock() if filerAddress == "" { - return fmt.Errorf("filer_etc: filer address is empty") + return fmt.Errorf("filer_etc: no filer discovered yet - please ensure a filer is running and accessible") } // Use the pb.WithGrpcFilerClient helper similar to existing code