SigNoz/signoz · critical

ErrCodeAuditExportFailed

ErrCodeAuditExportFailed

Error message

failed to open audit file %q

What it means

The SigNoz EE file auditor provider failed to os.OpenFile the configured audit log path with append/create/write-only mode; the OS error is wrapped with code ErrCodeAuditExportFailed.

Source

Thrown at ee/auditor/fileauditor/provider.go:42

	build     version.Build
	server    *auditorserver.Server
	marshaler plog.JSONMarshaler
	file      *os.File
	mu        sync.Mutex
}

func NewFactory(licensing licensing.Licensing, build version.Build) factory.ProviderFactory[auditor.Auditor, auditor.Config] {
	return factory.NewProviderFactory(factory.MustNewName("file"), func(ctx context.Context, providerSettings factory.ProviderSettings, config auditor.Config) (auditor.Auditor, error) {
		return newProvider(ctx, providerSettings, config, licensing, build)
	})
}

func newProvider(_ context.Context, providerSettings factory.ProviderSettings, config auditor.Config, licensing licensing.Licensing, build version.Build) (auditor.Auditor, error) {
	settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/ee/auditor/fileauditor")

	file, err := os.OpenFile(config.File.Path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
	if err != nil {
		return nil, errors.Wrapf(err, errors.TypeInvalidInput, auditor.ErrCodeAuditExportFailed, "failed to open audit file %q", config.File.Path)
	}

	provider := &provider{
		settings:  settings,
		config:    config,
		licensing: licensing,
		build:     build,
		marshaler: plog.JSONMarshaler{},
		file:      file,
	}

	server, err := auditorserver.New(settings,
		auditorserver.Config{
			BufferSize:    config.BufferSize,
			BatchSize:     config.BatchSize,
			FlushInterval: config.FlushInterval,
		},
		provider.export,

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Verify the path's parent directory exists and is writable by the signoz process user (mkdir -p && chown)
  2. Mount a writable volume at the audit path in docker/k8s
  3. Fix the configured path (remove trailing slash / ensure it's a file path, not a directory)
  4. Relax SELinux/AppArmor or run with correct fsGroup in k8s

Example fix

# before
file:
  path: /var/log/signoz/audit.log  # dir missing, no perms
# after
mkdir -p /var/log/signoz && chown signoz:signoz /var/log/signoz
# or mount a volume at that path
Defensive patterns

Strategy: fallback

Validate before calling

path := cfg.File.Path
if fi, err := os.Stat(filepath.Dir(path)); err != nil || !fi.IsDir() { log.Fatal("audit dir missing/not a dir:", filepath.Dir(path)) }
if err := unix.Access(path, unix.W_OK); err != nil { /* fix perms before start */ }

Try / catch

if _, err := fileauditor.New(ctx, settings, cfg, lic, build); err != nil { if strings.Contains(err.Error(), "failed to open audit file") { fix perms/dir; retry once }; else { fatal } }

Prevention

When it happens

Trigger: Starting SigNoz EE with auditor type "file" where config.File.Path points to a directory that doesn't exist, a read-only filesystem, a permission-denied location, or a path that is itself a directory.

Common situations: Running the container as a non-root user without write access to /var/signoz or the mounted volume; path typo or missing parent dir; container with read-only root FS and no volume for audit logs; SELinux denials.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/4a687b4e9e3a02e2. Report an issue: GitHub.