benbjohnson/litestream · error

failed to configure replica for %s: %w

Error message

failed to configure replica for %s: %w

What it means

Each discovered database gets a deep copy of the replica config with its path made unique (suffixed with the database's relative path) so databases don't overwrite each other in the replica destination. If cloneReplicaConfigWithRelativePath fails to derive that unique path, the error is wrapped with the database path.

Source

Thrown at cmd/litestream/main.go:909

		metaPathCopy := filepath.Join(baseMetaDir, relPath+litestream.MetaDirSuffix)
		dbConfigCopy.MetaPath = &metaPathCopy
		dbConfigCopy.MetaDir = nil
	case dbc.MetaPath != nil:
		baseMetaPath, err := expand(*dbc.MetaPath)
		if err != nil {
			return nil, fmt.Errorf("failed to expand meta path for %s: %w", dbPath, err)
		}
		metaPathCopy := deriveMetaPathForDirectoryEntry(baseMetaPath, relPath)
		dbConfigCopy.MetaPath = &metaPathCopy
		dbConfigCopy.MetaDir = nil
	}

	// Deep copy replica config and make path unique per database.
	// This prevents all databases from writing to the same replica path.
	if dbc.Replica != nil {
		replicaCopy, err := cloneReplicaConfigWithRelativePath(dbc.Replica, relPath)
		if err != nil {
			return nil, fmt.Errorf("failed to configure replica for %s: %w", dbPath, err)
		}
		dbConfigCopy.Replica = replicaCopy
	}

	// Also handle deprecated 'replicas' array field.
	if len(dbc.Replicas) > 0 {
		dbConfigCopy.Replicas = make([]*ReplicaConfig, len(dbc.Replicas))
		for i, replica := range dbc.Replicas {
			replicaCopy, err := cloneReplicaConfigWithRelativePath(replica, relPath)
			if err != nil {
				return nil, fmt.Errorf("failed to configure replica %d for %s: %w", i, dbPath, err)
			}
			dbConfigCopy.Replicas[i] = replicaCopy
		}
	}

	return NewDBFromConfig(&dbConfigCopy)
}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Check the replica URL syntax in the config (e.g. s3://bucket/prefix) and fix it.
  2. Inspect the wrapped inner error for the exact parse/join failure and the offending db path.
  3. Rename the database file to avoid problematic characters in its relative path.
  4. Verify the replica config is valid by testing it against a single-DB (non-directory) setup.

Example fix

# before
replica:
  url: s3:bucket/db   # malformed

# after
replica:
  url: s3://mybucket/litestream
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(replicaURL)
if err != nil || u.Scheme == "" {
    return fmt.Errorf("invalid replica url %q", replicaURL)
}

Prevention

When it happens

Trigger: cloneReplicaConfigWithRelativePath(dbc.Replica, relPath) returns an error for a specific database — e.g. the replica (bucket/path) URL cannot be parsed or extended with the relative path suffix.

Common situations: Invalid replica URL format in the config; replica path template that can't accept the appended relative path; unusual characters in a database's relative path breaking URL joining.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/8501bfc110b1dd40. Report an issue: GitHub.