diff --git a/include/isocline.h b/include/isocline.h
--- a/include/isocline.h
+++ b/include/isocline.h
@@ -45,7 +45,7 @@
 /// \{
 
 /// Isocline version: 102 = 1.0.2.
-#define IC_VERSION   (103)  
+#define IC_VERSION   (104)  
 
 
 /// Read input from the user using rich editing abilities.
diff --git a/isocline.cabal b/isocline.cabal
--- a/isocline.cabal
+++ b/isocline.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           isocline
-version:        1.0.3
+version:        1.0.4
 synopsis:       A portable alternative to GNU Readline
 description:    ![logo](https://raw.githubusercontent.com/daanx/isocline/main/doc/isocline-inline.svg) A Haskell wrapper around the [Isocline C library](https://github.com/daanx/isocline#readme) which can provide an alternative to GNU Readline. (The Isocline library is included whole and there are no runtime dependencies).
                 Please see the [readme](https://github.com/daanx/isocline/haskell#readme) on GitHub for more information.
diff --git a/src/term.c b/src/term.c
--- a/src/term.c
+++ b/src/term.c
@@ -351,6 +351,7 @@
   // detect color palette
   // COLORTERM takes precedence
   const char* colorterm = getenv("COLORTERM");  
+  const char* eterm = getenv("TERM");    
   if (ic_contains(colorterm,"24bit") || ic_contains(colorterm,"truecolor") || ic_contains(colorterm,"direct")) { 
     term->palette = ANSIRGB; 
   }
@@ -366,7 +367,6 @@
   else if (getenv("VSCODE_PID") != NULL) { term->palette = ANSIRGB; } // vscode terminal
   else {
     // and otherwise fall back to checking TERM
-    const char* eterm = getenv("TERM");
     if (ic_contains(eterm,"truecolor") || ic_contains(eterm,"direct") || ic_contains(colorterm,"24bit")) {
       term->palette = ANSIRGB;
     }
@@ -382,7 +382,7 @@
       term->palette = MONOCHROME; 
     }
   }
-  debug_msg("term: color-bits: %d (COLORTERM=%s, TERM=%s)\n", term_get_color_bits(term), colorterm, term);
+  debug_msg("term: color-bits: %d (COLORTERM=%s, TERM=%s)\n", term_get_color_bits(term), colorterm, eterm);
   
   // read COLUMS/LINES from the environment for a better initial guess.
   const char* env_columns = getenv("COLUMNS");
@@ -985,7 +985,10 @@
 static bool term_esc_query_color_raw(term_t* term, int color_idx, uint32_t* color ) {
   char buf[128+1];
   snprintf(buf,128,"\x1B]4;%d;?\x1B\\", color_idx);
-  if (!term_esc_query_raw( term, buf, buf, 128 )) return false;
+  if (!term_esc_query_raw( term, buf, buf, 128 )) {
+    debug_msg("esc query response not received\n");
+    return false;
+  }
   if (buf[0] != '4') return false;
   const char* rgb = strchr(buf,':');
   if (rgb==NULL) return false;
@@ -1004,6 +1007,7 @@
 
 // update ansi 16 color palette for better color approximation
 static void term_update_ansi16(term_t* term) {
+  debug_msg("update ansi colors\n");
   #if defined(GIO_CMAP)
   // try ioctl first (on Linux)
   uint8_t cmap[48];
@@ -1021,6 +1025,8 @@
     debug_msg("ioctl GIO_CMAP failed: entry 1: 0x%02x%02x%02x\n", cmap[3], cmap[4], cmap[5]);
   }
   #endif
+  // this seems to be unreliable on some systems (Ubuntu+Gnome terminal) so only enable when known ok.
+  #if __APPLE__
   // otherwise use OSC 4 escape sequence query
   tty_start_raw(term->tty);
   for(ssize_t i = 0; i < 16; i++) {
@@ -1030,6 +1036,7 @@
     ansi256[i] = color;
   }  
   tty_end_raw(term->tty);  
+  #endif
 }
 
 static void term_init_raw(term_t* term) {
diff --git a/src/tty.c b/src/tty.c
--- a/src/tty.c
+++ b/src/tty.c
@@ -236,7 +236,10 @@
   buf[0] = 0;
   ssize_t len = 0;
   uint8_t c = 0;
-  if (!tty_readc_noblock(tty, &c, tty->esc_initial_timeout) || c != '\x1B') return false;
+  if (!tty_readc_noblock(tty, &c, 2*tty->esc_initial_timeout) || c != '\x1B') {
+    debug_msg("initial esc response failed: 0x%02x\n", c);
+    return false;
+  }
   if (!tty_readc_noblock(tty, &c, tty->esc_timeout) || (c != esc_start)) return false;
   while( len < buflen ) {
     if (!tty_readc_noblock(tty, &c, tty->esc_timeout)) return false;
diff --git a/src/tty_esc.c b/src/tty_esc.c
--- a/src/tty_esc.c
+++ b/src/tty_esc.c
@@ -338,6 +338,26 @@
   return (code != KEY_NONE ? (code | modifiers) : KEY_NONE);
 }
 
+static code_t tty_read_osc( tty_t* tty, uint8_t* ppeek, long esc_timeout ) {
+  debug_msg("discard OSC response..\n");
+  // keep reading until termination: OSC is terminated by BELL, or ESC \ (ST)  (and STX)
+  while (true) {
+    uint8_t c = *ppeek;
+    if (c <= '\x07') {  // BELL and anything below (STX, ^C, ^D)
+      if (c != '\x07') { tty_cpush_char( tty, c ); }
+      break;
+    }
+    else if (c=='\x1B') {
+      uint8_t c1;
+      if (!tty_readc_noblock(tty, &c1, esc_timeout)) break;
+      if (c1=='\\') break;
+      tty_cpush_char(tty,c1);
+    }
+    if (!tty_readc_noblock(tty, ppeek, esc_timeout)) break;
+  }
+  return KEY_NONE;
+}
+
 ic_private code_t tty_read_esc(tty_t* tty, long esc_initial_timeout, long esc_timeout) {
   code_t  mods = 0;
   uint8_t peek = 0;
@@ -367,6 +387,12 @@
     }
     // treat all as standard SS3 'O'
     return tty_read_csi(tty,'O',peek,mods, esc_timeout);  // ESC [Oo?] ...
+  }
+
+  // OSC: we may get a delayed query response; ensure it is ignored
+  if (peek == ']') {
+    if (!tty_readc_noblock(tty, &peek, esc_timeout)) goto alt;
+    return tty_read_osc(tty, &peek, esc_timeout);  // ESC ] ...
   }
 
 alt:  
