benbjohnson/litestream · critical

failed to create GCS client (bucket: %s): %w

Error message

failed to create GCS client (bucket: %s): %w

What it means

The GCS replica client could not construct a Google Cloud Storage client during Init(). storage.NewClient(ctx) uses Application Default Credentials and underlying HTTP/gRPC transport; any failure (credentials, transport init, project metadata lookup) is wrapped with the configured bucket name for context. Init() is idempotent — it returns immediately if the client already exists — so this only fires on the first client creation attempt.

Source

Thrown at gs/replica_client.go:87

	return client, nil
}

// Type returns "gs" as the client type.
func (c *ReplicaClient) Type() string {
	return ReplicaClientType
}

// Init initializes the connection to GS. No-op if already initialized.
func (c *ReplicaClient) Init(ctx context.Context) (err error) {
	c.mu.Lock()
	defer c.mu.Unlock()

	if c.client != nil {
		return nil
	}

	if c.client, err = storage.NewClient(ctx); err != nil {
		return fmt.Errorf("failed to create GCS client (bucket: %s): %w", c.Bucket, err)
	}
	c.bkt = c.client.Bucket(c.Bucket)

	return nil
}

// DeleteAll deletes all LTX files.
func (c *ReplicaClient) DeleteAll(ctx context.Context) error {
	if err := c.Init(ctx); err != nil {
		return err
	}

	// Iterate over every object and delete it.
	internal.OperationTotalCounterVec.WithLabelValues(ReplicaClientType, "LIST").Inc()
	for it := c.bkt.Objects(ctx, &storage.Query{Prefix: c.Path + "/"}); ; {
		attrs, err := it.Next()
		if errors.Is(err, iterator.Done) {
			break

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Set GOOGLE_APPLICATION_CREDENTIALS to a valid service-account JSON key with storage access to the bucket
  2. If outside GCP, run `gcloud auth application-default login` or pass explicit credentials options to storage.NewClient
  3. Verify the key file exists and is readable by the litestream process (check container mounts and file permissions)
  4. Confirm network access to the GCS/metadata endpoints (oauth2.googleapis.com, metadata.google.internal)
  5. Check the wrapped cause (%w) for the specific underlying failure, e.g. credential parse errors

Example fix

// before (Dockerfile) — no credentials provided
CMD ["litestream", "replicate", "/etc/litestream.yml"]

// after
COPY sa-key.json /etc/litestream/sa-key.json
ENV GOOGLE_APPLICATION_CREDENTIALS=/etc/litestream/sa-key.json
CMD ["litestream", "replicate", "/etc/litestream.yml"]
Defensive patterns

Strategy: validation

Validate before calling

if os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") == "" && !runningOnGCP() {
    return fmt.Errorf("no GCP credentials found: set GOOGLE_APPLICATION_CREDENTIALS")
}

Try / catch

if err := rc.Init(ctx); err != nil {
    var credErr *googleapi.Error
    if os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") == "" {
        // fix credentials before retrying
    }
    return err
}

Prevention

When it happens

Trigger: Calling Init() on a gs.ReplicaClient when GOOGLE_APPLICATION_CREDENTIALS is unset/unreadable, the credentials file is invalid or expired, the metadata server is unreachable (e.g. outside GCP without explicit credentials), or the storage client transport fails to initialize.

Common situations: Running litestream in Docker/K8s without mounting the service-account key; GOOGLE_APPLICATION_CREDENTIALS pointing to a deleted or malformed JSON file; running locally with `gcloud auth application-default login` never executed; GCE metadata endpoint blocked by network policy.

Related errors


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