diff --git a/src/pkg/registry/client.go b/src/pkg/registry/client.go
index 6b4447e6f..9d971dc4d 100644
--- a/src/pkg/registry/client.go
+++ b/src/pkg/registry/client.go
@@ -351,16 +351,24 @@ func (c *client) PullBlob(repository, digest string) (int64, io.ReadCloser, erro
 	if err != nil {
 		return 0, nil, err
 	}
+
+	req.Header.Add(http.CanonicalHeaderKey("Accept-Encoding"), "identity")
 	resp, err := c.do(req)
 	if err != nil {
 		return 0, nil, err
 	}
+
+	var size int64
 	n := resp.Header.Get(http.CanonicalHeaderKey("Content-Length"))
-	size, err := strconv.ParseInt(n, 10, 64)
-	if err != nil {
-		defer resp.Body.Close()
-		return 0, nil, err
+	// no content-length is acceptable, which can taken from manifests
+	if len(n) > 0 {
+		size, err = strconv.ParseInt(n, 10, 64)
+		if err != nil {
+			defer resp.Body.Close()
+			return 0, nil, err
+		}
 	}
+
 	return size, resp.Body, nil
 }
 
diff --git a/src/replication/transfer/image/transfer.go b/src/replication/transfer/image/transfer.go
index 7a02cdc7c..57ccf86ac 100644
--- a/src/replication/transfer/image/transfer.go
+++ b/src/replication/transfer/image/transfer.go
@@ -16,12 +16,13 @@ package image
 
 import (
 	"errors"
+	"net/http"
+	"strings"
+
 	"github.com/docker/distribution/manifest/manifestlist"
 	"github.com/docker/distribution/manifest/schema1"
 	common_http "github.com/goharbor/harbor/src/common/http"
 	v1 "github.com/opencontainers/image-spec/specs-go/v1"
-	"net/http"
-	"strings"
 
 	"github.com/docker/distribution"
 	"github.com/docker/distribution/manifest/schema2"
@@ -243,12 +244,13 @@ func (t *transfer) copyContent(content distribution.Descriptor, srcRepo, dstRepo
 	// the media type of the layer or config can be "application/octet-stream",
 	// schema1.MediaTypeManifestLayer, schema2.MediaTypeLayer, schema2.MediaTypeImageConfig
 	default:
-		return t.copyBlob(srcRepo, dstRepo, digest)
+		return t.copyBlob(srcRepo, dstRepo, digest, content.Size)
 	}
 }
 
 // copy the layer or artifact config from the source registry to destination
-func (t *transfer) copyBlob(srcRepo, dstRepo, digest string) error {
+// the size parameter is taken from manifests.
+func (t *transfer) copyBlob(srcRepo, dstRepo, digest string, sizeFromDescriptor int64) error {
 	if t.shouldStop() {
 		return nil
 	}
@@ -269,6 +271,12 @@ func (t *transfer) copyBlob(srcRepo, dstRepo, digest string) error {
 		return err
 	}
 	defer data.Close()
+	// get size 0 from PullBlob, use size from distribution.Descriptor instead.
+	if size == 0 {
+		size = sizeFromDescriptor
+		t.logger.Debugf("the blob size from remote registry is 0, use size %d from manifests instead", size)
+	}
+
 	if err = t.dst.PushBlob(dstRepo, digest, size, data); err != nil {
 		t.logger.Errorf("failed to pushing the blob %s: %v", digest, err)
 		return err