grpc/grpc-go · warning
profiling may be initialized at most once
Error message
profiling may be initialized at most once
What it means
Returned by profiling.InitStats when it has already been called once. InitStats uses an atomic CompareAndSwap on statsInitialized (0->1) to enforce single initialization; a second call finds it already 1 and returns errAlreadyInitialized. This is by design—profiling's StreamStats CircularBuffer is process-global and must be set up exactly once.
Source
Thrown at internal/profiling/profiling.go:202
stat.mu.Unlock()
}
// statsInitialized is 0 before InitStats has been called. Changed to 1 by
// exactly one call to InitStats.
var statsInitialized int32
// Stats for the last defaultStreamStatsBufsize RPCs will be stored in memory.
// This can be configured by the registering server at profiling service
// initialization with google.golang.org/grpc/profiling/service.ProfilingConfig
const defaultStreamStatsSize uint32 = 16 << 10
// StreamStats is a CircularBuffer containing data from the last N RPC calls
// served, where N is set by the user. This will contain both server stats and
// client stats (but each stat will be tagged with whether it's a server or a
// client in its Tags).
var StreamStats *buffer.CircularBuffer
var errAlreadyInitialized = errors.New("profiling may be initialized at most once")
// InitStats initializes all the relevant Stat objects. Must be called exactly
// once per lifetime of a process; calls after the first one will return an
// error.
func InitStats(streamStatsSize uint32) error {
var err error
if !atomic.CompareAndSwapInt32(&statsInitialized, 0, 1) {
return errAlreadyInitialized
}
if streamStatsSize == 0 {
streamStatsSize = defaultStreamStatsSize
}
StreamStats, err = buffer.NewCircularBuffer(streamStatsSize)
if err != nil {
return err
}View on GitHub (pinned to 0c51461d27)
Solutions
- Call profiling.InitStats exactly once per process lifecycle, typically at startup.
- In tests, guard re-initialization with a sync.Once or reset statsInitialized via test helpers if available.
- If using profiling/service.RegisterProfiling, ensure it is only called once across all servers in the binary.
- Check IsEnabled and whether StreamStats is already non-nil before calling InitStats.
Example fix
// before: may call InitStats multiple times
func setupProfiling(size uint32) error {
return profiling.InitStats(size)
}
// after: guard with sync.Once
var initOnce sync.Once
var initErr error
func setupProfiling(size uint32) error {
initOnce.Do(func() { initErr = profiling.InitStats(size) })
return initErr
} Defensive patterns
Strategy: validation
Validate before calling
// Guard InitStats with sync.Once to prevent double initialization.
var profilingOnce sync.Once
var profilingInitErr error
func safeInitStats(size uint32) error {
profilingOnce.Do(func() { profilingInitErr = profiling.InitStats(size) })
return profilingInitErr
} Try / catch
err := profiling.InitStats(size)
if err != nil && strings.Contains(err.Error(), "at most once") {
// already initialized; safe to ignore
return nil
} Prevention
- Call profiling.InitStats exactly once at process startup.
- Guard initialization with sync.Once in shared setup code.
- In tests, reset state or skip re-initialization for the profiling service.
- Check profiling.IsEnabled() or StreamStats != nil before initializing.
When it happens
Trigger: Calling profiling.InitStats (or profiling/service RegisterProfiling which calls InitStats internally) more than once in the same process. Common in tests that start multiple profiling services, or in long-running servers that reinitialize profiling.
Common situations: Test suites that call InitStats in setup without teardown; multiple gRPC servers in one binary each trying to register the profiling service; hot-reload or restart logic that re-runs initialization code.
Related errors
- buffer size is not an exponent of two
- invalid method name: should start with /
- invalid method name: suffix /method is missing
- server-side auth info is not of type alts.AuthInfo
- message authentication failed
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/479db05b2265abfe.
Report an issue: GitHub.