diff --git a/include/maestro/i_cdo.h b/include/maestro/i_cdo.h
index d4e2fbd4203dee4eda01434746b401bca5126270..93f20dabdbec4ee7becdf4c5de4b2d37fd3b6ae1 100644
--- a/include/maestro/i_cdo.h
+++ b/include/maestro/i_cdo.h
@@ -156,7 +156,14 @@ typedef uint32_t mstro_cdo_state;
 /** The NIL UUID */
 #define MSTRO_CDO_ID_INVALID { .id = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 } }
 
-/** return a string describing the CDO state @arg s */
+/** return a string describing the CDO state @arg s
+ **
+ ** The string is owned by this function, but this function can safely
+ ** be called from multiple threads (the buffer is thread-local). The
+ ** buffer will be re-used by subsequent calls in the same thread
+ ** after a small number of invocations (currently: 3, see @ref
+ ** MAX_STATE_DESCRIPTION_BUFFERS).
+ **/
 const char *
 mstro_cdo_state_describe(mstro_cdo_state s);
 
diff --git a/maestro/cdo.c b/maestro/cdo.c
index 867151da57d7c737e0658ceea7c34ea9f3d879bf..8ec685e4af995885e05df2eb9db64812d32c239e 100644
--- a/maestro/cdo.c
+++ b/maestro/cdo.c
@@ -1633,22 +1633,34 @@ struct {
 /** a reasonably safe way to count the number of entries in an array of structures */
 #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
 
+
+/** we support this many concurrent state buffers in flight per
+ * thread. Hideous, but callers typically will use this function in a
+ * PRINT statement, with up to two states (to compare them) at most
+ */
+
+#define MAX_STATE_DESCRIPTION_BUFFERS 3
 const char *
 mstro_cdo_state_describe(mstro_cdo_state s)
 {
-  static _Thread_local char buf[sizeof(states_and_names)];
+  static _Thread_local char buf[MAX_STATE_DESCRIPTION_BUFFERS][sizeof(states_and_names)];
+  static _Thread_local size_t bufid = 0;
 
-  buf[0]='\0';
+  // switch to new buffer
+  bufid = (bufid+1) % MAX_STATE_DESCRIPTION_BUFFERS;
+  
+  buf[bufid][0]='\0';
 
   if(s==MSTRO_CDO_STATE_INVALID)
     return "INVALID";
   else {
     for(size_t i=0; i<COUNT_OF(states_and_names); i++) {
       if(s&states_and_names[i].state) {
-        strcat(buf, states_and_names[i].name);
+        strcat(buf[bufid], states_and_names[i].name);
       }
     }
-    return buf+1; /* cut off leading '|' we put there for simplicity
+    
+    return buf[bufid]+1; /* cut off leading '|' we put there for simplicity
                    * of the loop above */
   }
 }