diff --git a/autoload/coc/util.vim b/autoload/coc/util.vim
index fc21f134c3a..ac214a82cd4 100644
--- a/autoload/coc/util.vim
+++ b/autoload/coc/util.vim
@@ -890,3 +890,12 @@ function! coc#util#pclose()
     endif
   endfor
 endfunction
+
+function! coc#util#init_virtual_hl()
+  let names = ['Error', 'Warning', 'Info', 'Hint']
+  for name in names
+    if !hlexists('Coc'.name.'VirtualText')
+      exe 'hi default link Coc'.name.'VirtualText Coc'.name.'Sign'
+    endif
+  endfor
+endfunction
diff --git a/doc/coc.txt b/doc/coc.txt
index 125dec13924..10b5734547e 100644
--- a/doc/coc.txt
+++ b/doc/coc.txt
@@ -1586,6 +1586,30 @@ CocHintSign 					*CocHintSign*
 
   The highlight used for hint signs.
 
+CocErrorVirtualText 					*CocErrorVirtualText*
+
+  Default: `hi default link CocErrorVirtualText  CocErrorSign`
+
+  The highlight used for error signs.
+
+CocWarningVirtualText 					*CocWarningVirtualText*
+
+  Default: `hi default link CocWarningVirtualText CocWarningSign`
+
+  The highlight used for warning signs.
+
+CocInfoVirtualText 					*CocInfoVirtualText*
+
+  Default: `hi default link CocInfoVirtualText CocInfoSign`
+
+  The highlight used for information signs.
+
+CocHintVirtualText 					*CocHintVirtualText*
+
+  Default: `hi default link CocHintVirtualText CocHintSign`
+
+  The highlight used for hint signs.
+
 CocErrorHighlight 				*CocErrorHighlight*
 
   Default: `hi default link CocErrorHighlight   CocUnderline`
diff --git a/src/diagnostic/manager.ts b/src/diagnostic/manager.ts
index 7dc48feb7b0..e3538d42039 100644
--- a/src/diagnostic/manager.ts
+++ b/src/diagnostic/manager.ts
@@ -132,12 +132,6 @@ export class DiagnosticManager implements Disposable {
       this.setConfiguration(e)
     }, null, this.disposables)
 
-    let { errorSign, warningSign, infoSign, hintSign } = this.config
-    nvim.command(`sign define CocError   text=${errorSign}   linehl=CocErrorLine texthl=CocErrorSign`, true)
-    nvim.command(`sign define CocWarning text=${warningSign} linehl=CocWarningLine texthl=CocWarningSign`, true)
-    nvim.command(`sign define CocInfo    text=${infoSign}    linehl=CocInfoLine  texthl=CocInfoSign`, true)
-    nvim.command(`sign define CocHint    text=${hintSign}    linehl=CocHintLine  texthl=CocHintSign`, true)
-
     // create buffers
     for (let doc of workspace.documents) {
       this.createDiagnosticBuffer(doc)
@@ -150,6 +144,19 @@ export class DiagnosticManager implements Disposable {
     workspace.configurations.onError(async () => {
       this.setConfigurationErrors()
     }, null, this.disposables)
+
+    let { errorSign, warningSign, infoSign, hintSign } = this.config
+    nvim.pauseNotification()
+    nvim.command(`sign define CocError   text=${errorSign}   linehl=CocErrorLine texthl=CocErrorSign`, true)
+    nvim.command(`sign define CocWarning text=${warningSign} linehl=CocWarningLine texthl=CocWarningSign`, true)
+    nvim.command(`sign define CocInfo    text=${infoSign}    linehl=CocInfoLine  texthl=CocInfoSign`, true)
+    nvim.command(`sign define CocHint    text=${hintSign}    linehl=CocHintLine  texthl=CocHintSign`, true)
+    if (this.config.virtualText) {
+      nvim.call('coc#util#init_virtual_hl', [], true)
+    }
+    nvim.resumeNotification(false, true).catch(_e => {
+      // noop
+    })
   }
 
   private createDiagnosticBuffer(doc: Document): void {