gastownhall/beads · error

write proxy secret: %w

Error message

write proxy secret: %w

What it means

Wraps a failure from identity.WriteSecret(p.rootDir), which persists the shared proxy secret file under the database root directory. The control-plane authentication protocol needs this secret on disk before the proxy can serve; if writing it fails, startup aborts with this wrapped error.

Source

Thrown at internal/storage/dbproxy/proxy/server.go:239

	}

	addr := fmt.Sprintf("127.0.0.1:%d", p.port)

	ln, err := net.Listen("tcp", addr)
	if err != nil {
		return fmt.Errorf("listen on %s: %w", addr, err)
	}

	p.listener = ln
	defer func() { _ = ln.Close() }()
	p.stats.IncListenAndServe()
	dataPort, ok := ln.Addr().(*net.TCPAddr)
	if !ok {
		return fmt.Errorf("proxy: unexpected data listener address %T", ln.Addr())
	}

	if _, err := identity.WriteSecret(p.rootDir); err != nil {
		return fmt.Errorf("write proxy secret: %w", err)
	}

	var identMu sync.RWMutex
	identReply := identity.IdentReply{
		Schema:   pidfile.SchemaV2,
		Role:     pidfile.KindProxy,
		DataPort: dataPort.Port,
	}
	control, err := startControl(p.rootDir, func() identity.IdentReply {
		identMu.RLock()
		defer identMu.RUnlock()
		return identReply
	})
	if err != nil {
		return fmt.Errorf("start control listener: %w", err)
	}
	defer func() { _ = control.Close() }()

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check permissions on rootDir and ensure the proxy process user can create/write files there (chown/chmod)
  2. Verify the filesystem is writable (not read-only) and has free space
  3. Confirm rootDir exists and is a directory before starting the proxy
  4. Remove a stale/corrupt secret file if one exists and retry

Example fix

// before
_ = os.MkdirAll(rootDir, 0o755) // wrong owner, write fails at runtime
// after
if err := os.MkdirAll(rootDir, 0o700); err != nil { return err }
// ensure the running user owns rootDir before ListenAndServe
Defensive patterns

Strategy: validation

Validate before calling

// Before ListenAndServe, verify rootDir is writable
if err := os.MkdirAll(rootDir, 0o700); err != nil { return err }
test := filepath.Join(rootDir, ".write-test")
if err := os.WriteFile(test, nil, 0o600); err != nil {
    return fmt.Errorf("rootDir not writable: %w", err)
}
os.Remove(test)

Try / catch

if err := p.ListenAndServe(ctx); err != nil {
    if errors.Is(err, fs.ErrPermission) {
        log.Fatalf("cannot write proxy secret: check ownership of %s", rootDir)
    }
    log.Fatal(err)
}

Prevention

When it happens

Trigger: ListenAndServe -> identity.WriteSecret returns an error, typically due to filesystem permission problems, a read-only mount, or rootDir not existing.

Common situations: Database directory owned by a different user after switching service accounts; disk full; rootDir created by a previous run with restrictive permissions; running on a read-only container volume; macOS/Windows path permission quirks.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/b732ea916f003cc6. Report an issue: GitHub.