benbjohnson/litestream · error

cannot specify a replica URL and the -config flag

Error message

cannot specify a replica URL and the -config flag

What it means

`restore` supports two mutually exclusive ways to pick the restore source: a positional replica URL argument, or the -config flag pointing at a config file. Supplying both is ambiguous, so the command rejects it up front with this error. Only when the first positional arg is a URL (litestream.IsURL) is the -config conflict checked.

Source

Thrown at cmd/litestream/restore.go:98

		opt.IntegrityCheck = litestream.IntegrityCheckQuick
	case "full":
		opt.IntegrityCheck = litestream.IntegrityCheckFull
	default:
		return fmt.Errorf("invalid -integrity-check value: %s", *integrityCheck)
	}

	// Parse timestamp, if specified.
	if *timestampStr != "" {
		if opt.Timestamp, err = time.Parse(time.RFC3339, *timestampStr); err != nil {
			return errors.New("invalid -timestamp, must specify in ISO 8601 format (e.g. 2000-01-01T00:00:00Z)")
		}
	}

	// Determine replica to restore from.
	var r *litestream.Replica
	if litestream.IsURL(fs.Arg(0)) {
		if *configPath != "" {
			return fmt.Errorf("cannot specify a replica URL and the -config flag")
		}
		if r, err = c.loadFromURL(ctx, fs.Arg(0), *ifDBNotExists, &opt); errors.Is(err, errSkipDBExists) {
			slog.Info("database already exists, skipping")
			return nil
		} else if err != nil {
			return err
		}
	} else {
		if *configPath == "" {
			*configPath = DefaultConfigPath()
		}
		if r, err = c.loadFromConfig(ctx, fs.Arg(0), *configPath, !*noExpandEnv, *ifDBNotExists, &opt); errors.Is(err, errSkipDBExists) {
			slog.Info("database already exists, skipping")
			return nil
		} else if err != nil {
			return err
		}
	}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Drop -config when restoring directly from a replica URL
  2. Or drop the URL argument and instead select the db (and replica) via the config file with a db path argument
  3. If the URL comes from a variable that may be empty, guard the script so -config is only added when no URL is present

Example fix

// before
litestream restore s3://bucket/prefix -config /etc/litestream.yml -o out.db
// after
litestream restore s3://bucket/prefix -o out.db
Defensive patterns

Strategy: validation

Validate before calling

if replicaURL != "" && configPath != "" {
    return fmt.Errorf("pass either a replica URL or -config, not both")
}

Prevention

When it happens

Trigger: `litestream restore s3://bucket/prefix -config litestream.yml` — a replica URL as arg 0 while -config is also set.

Common situations: Users with a config file who also paste a replica URL from docs/scripts; automations that always append -config even when a URL form is used; shell scripts assembling the command from multiple variables.

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


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