benbjohnson/litestream · error
failed to marshal request: %w
Error message
failed to marshal request: %w
What it means
Before POSTing to the control socket, the register command serializes the RegisterDatabaseRequest (path + replica URL) with encoding/json. If json.Marshal fails, the request is wrapped as 'failed to marshal request'. In practice this is nearly impossible here because the payload contains only plain strings, so it signals a genuine internal invariant violation rather than user error.
Source
Thrown at cmd/litestream/register.go:69
// Create HTTP client that connects via Unix socket with timeout.
clientTimeout := time.Duration(*timeout) * time.Second
client := &http.Client{
Timeout: clientTimeout,
Transport: &http.Transport{
DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
return net.DialTimeout("unix", *socketPath, clientTimeout)
},
},
}
req := litestream.RegisterDatabaseRequest{
Path: dbPath,
ReplicaURL: replicaURL,
}
reqBody, err := json.Marshal(req)
if err != nil {
return fmt.Errorf("failed to marshal request: %w", err)
}
resp, err := client.Post("http://localhost/register", "application/json", bytes.NewReader(reqBody))
if err != nil {
return fmt.Errorf("failed to connect to control socket: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
var errResp litestream.ErrorResponse
if err := json.Unmarshal(body, &errResp); err == nil && errResp.Error != "" {
return fmt.Errorf("register failed: %s", errResp.Error)
}View on GitHub (pinned to 4ed7a308f6)
Solutions
- Verify you are running an unmodified litestream build (rebuild from source)
- Inspect the wrapped %w cause for the actual json.UnsupportedTypeError and check any custom MarshalJSON on RegisterDatabaseRequest
- If reproducible in a fork, ensure added fields are JSON-encodable
Defensive patterns
Strategy: try-catch
Try / catch
if err := registerCmd.Run(ctx, args); err != nil {
var e *fmt.wrapError
if errors.As(err, &e) && strings.Contains(err.Error(), "failed to marshal request") {
log.Fatalf("internal bug: non-marshalable request field: %v", err)
}
} Prevention
- Keep request structs limited to JSON-encodable types
- Rebuild from upstream source if you see this error
- Treat it as an internal-invariant bug and file an issue
When it happens
Trigger: A json.Marshal failure on the RegisterDatabaseRequest struct — only reachable if the struct fields become unsupported types (e.g. channels/funcs/cycles) in a modified build; not reachable with string fields in the current code.
Common situations: Almost never hit by end users; may appear if a fork or patch adds a non-marshalable field to RegisterDatabaseRequest, or a custom json.Marshaler on it returns an error.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- failed to format response: %w
- failed to format response: %w
- failed to format response: %w
- failed to format response: %w
- failed to marshal request: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/570e8409eb969de2.
Report an issue: GitHub.