tailscale/tailscale · error
start failed: %w
Error message
start failed: %w
What it means
logger.Start failed to begin the flush worker with the given transport, usually because the logger was already started or stopped. The logger is unusable and the extension will not record audit events.
Source
Thrown at ipn/auditlog/extension.go:102
// Create a new log store if this is the first logger.
// Otherwise, get the existing log store.
store, err := e.store.GetErr(func() (LogStore, error) {
return newDefaultLogStore(e.logf)
})
if err != nil {
return nil, fmt.Errorf("failed to create audit log store: %w", err)
}
logger := NewLogger(Opts{
Logf: e.logf,
RetryLimit: 32,
Store: store,
})
if err := logger.SetProfileID(profileID); err != nil {
return nil, fmt.Errorf("set profile failed: %w", err)
}
if err := logger.Start(transport); err != nil {
return nil, fmt.Errorf("start failed: %w", err)
}
return logger, nil
}
func (e *extension) controlClientChanged(cc controlclient.Client, profile ipn.LoginProfileView) (cleanup func()) {
logger, err := e.startNewLogger(cc, profile.ID())
e.mu.Lock()
e.logger = logger // nil on error
e.mu.Unlock()
if err != nil {
// If we fail to create or start the logger, log the error
// and return a nil cleanup function. There's nothing more
// we can do here.
//
// But [extension.getCurrentLogger] returns [noCurrentLogger]
// when the logger is nil. Since [noCurrentLogger] always
// fails with [errNoLogger], operations that must be audited
// but cannot will fail on platforms where the audit loggerView on GitHub (pinned to 6e0912f979)
Solutions
- Ensure Start is called exactly once per logger.
- Stop the previous logger before starting a new one on control client change.
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at ipn/auditlog/extension.go:102 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of tailscale/tailscale@6e0912f979 (2026-08-18).
Data as JSON: /api/errors/5d663884dd4283ab.
Report an issue: GitHub.