diff --git a/hgext/progress.py b/hgext/progress.py
--- a/hgext/progress.py
+++ b/hgext/progress.py
@@ -159,9 +159,9 @@ class progbar(object):
         if needprogress:
             used = 0
             if head:
-                used += len(head) + 1
+                used += encoding.colwidth(head) + 1
             if tail:
-                used += len(tail) + 1
+                used += encoding.colwidth(tail) + 1
             progwidth = termwidth - used - 3
             if total and pos <= total:
                 amt = pos * progwidth // total
diff --git a/tests/test-progress.t b/tests/test-progress.t
--- a/tests/test-progress.t
+++ b/tests/test-progress.t
@@ -275,3 +275,21 @@ display are different from each other.
   \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88 1/3\r (no-eol) (esc)
   \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88 2/3\r (no-eol) (esc)
               \r (no-eol) (esc)
+
+test calculation of bar width, when progress topic contains multi-byte
+characters, of which length of byte sequence and columns in display
+are different from each other.
+
+  $ cat >> $HGRCPATH <<EOF
+  > [progress]
+  > format = topic bar
+  > width= 21
+  > # progwidth should be 9 (= 21 - (8+1) - 3)
+  > EOF
+
+  $ hg --encoding utf-8 -y loop --total 3 3
+  \r (no-eol) (esc)
+  \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88 [         ]\r (no-eol) (esc)
+  \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88 [==>      ]\r (no-eol) (esc)
+  \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88 [=====>   ]\r (no-eol) (esc)
+                       \r (no-eol) (esc)