diff --git a/pkg/plugin/discovery/resolver/registry/registry.go b/pkg/plugin/discovery/resolver/registry/registry.go
index 28d3d1797c9f30e3d884cf00d4ed57930fd6a035..83ac03648dd3f3f5859a5d05f83ea5218cb0ac85 100644
--- a/pkg/plugin/discovery/resolver/registry/registry.go
+++ b/pkg/plugin/discovery/resolver/registry/registry.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/Masterminds/semver/v3"
 	"github.com/go-semantic-release/plugin-registry/pkg/client"
+	"github.com/go-semantic-release/plugin-registry/pkg/registry"
 	"github.com/go-semantic-release/semantic-release/v2/pkg/plugin"
 	"github.com/go-semantic-release/semantic-release/v2/pkg/plugin/discovery/resolver"
 )
@@ -82,7 +83,30 @@ func (r *Resolver) ResolvePlugin(pluginInfo *plugin.Info) (*resolver.PluginDownl
 }
 
 func (r *Resolver) BatchResolvePlugins(pluginInfos []*plugin.Info) (*resolver.BatchPluginDownloadInfo, error) {
-	return nil, fmt.Errorf("not implemented")
+	batchRequest := &registry.BatchRequest{
+		OS:      runtime.GOOS,
+		Arch:    runtime.GOARCH,
+		Plugins: make([]*registry.BatchRequestPlugin, len(pluginInfos)),
+	}
+	for i, pluginInfo := range pluginInfos {
+		versionConstraint := ""
+		if pluginInfo.Constraint != nil {
+			versionConstraint = pluginInfo.Constraint.String()
+		}
+		batchRequest.Plugins[i] = &registry.BatchRequestPlugin{
+			FullName:          pluginInfo.ShortNormalizedName,
+			VersionConstraint: versionConstraint,
+		}
+	}
+	batchResponse, err := r.client.SendBatchRequest(context.Background(), batchRequest)
+	if err != nil {
+		return nil, err
+	}
+
+	return &resolver.BatchPluginDownloadInfo{
+		URL:      batchResponse.DownloadURL,
+		Checksum: batchResponse.DownloadChecksum,
+	}, nil
 }
 
 func (r *Resolver) Names() []string {
diff --git a/pkg/plugin/manager/manager.go b/pkg/plugin/manager/manager.go
index 0e3e743853fff2a9401698709de993bd47717ab7..8ea720879b741b9adc13eb3acb51374181ea5d26 100644
--- a/pkg/plugin/manager/manager.go
+++ b/pkg/plugin/manager/manager.go
@@ -168,7 +168,7 @@ func (m *PluginManager) checkIfSameResolvers(infos []*plugin.Info) (string, bool
 
 func (m *PluginManager) FetchAllPlugins() error {
 	batchWasPossible, pInfos, err := m.PrefetchAllPluginsIfBatchIsPossible()
-	if err != nil {
+	if err != nil && pInfos == nil {
 		return err
 	}
 	if batchWasPossible {
@@ -195,7 +195,7 @@ func (m *PluginManager) PrefetchAllPluginsIfBatchIsPossible() (bool, []*plugin.I
 		// all plugins have the same resolver, and it supports batch resolving
 		bErr := m.discovery.FindPluginsWithBatchResolver(resolver, pInfos)
 		if bErr != nil {
-			return false, nil, bErr
+			return false, pInfos, bErr
 		}
 		return true, pInfos, nil
 	}