diff --git a/include/maestro/i_globals.h b/include/maestro/i_globals.h
index 16f154759bb3fbaa340fdcdf1d45c9ceb598e7a4..c96d89bc03adf0fcb2ccf51c3ded4e122f6af976 100644
--- a/include/maestro/i_globals.h
+++ b/include/maestro/i_globals.h
@@ -46,6 +46,7 @@
 #include <pthread.h>
 #include <mamba.h>
 #include "maestro/env.h"
+#include "logging.h"
 
 /** Init data; set at mstro_core_init() time; protected by @ref g_initdata_mtx */
 extern struct mstro_core_initdata * g_initdata;
@@ -180,5 +181,14 @@ extern struct erl_thread_team *g_ofi_cq_team;
 /** Event domain for handler continuations */
 extern mstro_event_domain g_mstro_pm_continuations;
 
+/** macro to check whether we are initilized and return suitable error immediately if not */
+
+#define MSTRO_API_NEEDS_INIT() do { \
+       	if(NULL==g_initdata) {    \
+	    LOG_ERR(MSTRO_LOG_MODULE_CORE, "Function %s cannot be called before mstro_init()\n", __func__); \
+	    return MSTRO_UNINIT;  \
+       	}                         \
+   } while(0)
+
 
 #endif /* MAESTRO_I_GLOBALS_H_ */
diff --git a/include/maestro/status.h b/include/maestro/status.h
index 5930fe3827808c214e749c91c83279628223d821..1b78e9132f77aeaa19dec6d8a4a8b69b1a77cd1f 100644
--- a/include/maestro/status.h
+++ b/include/maestro/status.h
@@ -55,6 +55,7 @@ extern "C" {
   typedef enum {
     MSTRO_OK = 0,     /**< successful completion of an operation */
     MSTRO_FAIL = 1,   /**< (generic) failure of an operation */
+    MSTRO_UNINIT,     /**< maestro-core not initialized */
     MSTRO_UNIMPL,     /**< function is yet unimplemented */
     MSTRO_INVARG,     /**< invalid argument */
     MSTRO_INVOUT,     /**< invalid output argument location */
diff --git a/maestro/cdo.c b/maestro/cdo.c
index b36a882ddfa1cc18453592ef65a13d38a1b09679..7680faa05e6656491df549e3624dd8a6acc6aea7 100644
--- a/maestro/cdo.c
+++ b/maestro/cdo.c
@@ -459,8 +459,9 @@ mstro_cdo_name(mstro_cdo cdo)
   }
 }
 
+static inline
 mstro_status
-mstro_cdo_declare_propagate(const char *name,
+mstro_cdo_declare__propagate(const char *name,
 		  mstro_cdo *result)
 {
   mstro_cdo_state_set(*result, MSTRO_CDO_STATE_CREATED);
@@ -564,7 +565,7 @@ mstro_cdo_declare_core(const char *name,
   }
 
   mstro_status s;
-  s = mstro_cdo_declare_propagate(name, result);
+  s = mstro_cdo_declare__propagate(name, result);
   if (s != MSTRO_OK)
     return s;
 
@@ -590,6 +591,8 @@ mstro_cdo_declare_async(const char *name,
                         mstro_cdo *result,
                         mstro_request *request)
 {
+  MSTRO_API_NEEDS_INIT();
+
    mstro_status status = MSTRO_UNIMPL;
    status = mstro_cdo_declare_core(name, attributes, result);
    /** if successful, fill in the request */
@@ -616,9 +619,12 @@ mstro_cdo_declare_async(const char *name,
 mstro_status
 mstro_cdo_declare(const char *name,
                   mstro_cdo_attributes attributes,
-		  mstro_cdo *result) {
+		  mstro_cdo *result)
+{
+  MSTRO_API_NEEDS_INIT();
 
   mstro_status status = MSTRO_UNIMPL;
+
   status = mstro_cdo_declare_core(name, attributes, result);
   /** if successful, increase statistics counter */
   if(status == MSTRO_OK) {
@@ -812,6 +818,7 @@ mstro_cdo__create_mamba_array(mstro_cdo cdo, int policy)
 mstro_status
 mstro_cdo_seal(mstro_cdo cdo)
 {
+  MSTRO_API_NEEDS_INIT();
   mstro_status status = mstro_cdo_declaration_seal(cdo);
   if (status == MSTRO_OK) {
       mstro_stats_add_counter(MSTRO_STATS_CAT_PROTOCOL, MSTRO_STATS_L_PC_NUM_SEAL, 1);
@@ -823,6 +830,7 @@ mstro_cdo_seal(mstro_cdo cdo)
 mstro_status
 mstro_cdo_seal_async(mstro_cdo cdo, mstro_request *request)
 {
+  MSTRO_API_NEEDS_INIT();
   mstro_status status = MSTRO_UNIMPL;
   if(cdo==NULL) {
     ERR("NULL CDO illegal\n");
@@ -1456,6 +1464,7 @@ mstro_request_free(mstro_request request)
 mstro_status
 mstro_cdo_declaration_seal(mstro_cdo cdo)
 {
+  MSTRO_API_NEEDS_INIT();
   mstro_status status = MSTRO_UNIMPL;
 
   if(cdo==NULL) {
@@ -1629,6 +1638,7 @@ BAILOUT:
 mstro_status
 mstro_cdo_offer_async(mstro_cdo cdo, mstro_request *request)
 {
+  MSTRO_API_NEEDS_INIT();
   mstro_status status;
   if(cdo==NULL) {
     ERR("NULL CDO invalid\n");
@@ -1740,6 +1750,7 @@ mstro_cdo_offer_async(mstro_cdo cdo, mstro_request *request)
 mstro_status
 mstro_cdo_offer(mstro_cdo cdo)
 {
+  MSTRO_API_NEEDS_INIT();
   mstro_status status;
   if(cdo==NULL) {
     ERR("NULL CDO invalid\n");
@@ -1863,6 +1874,7 @@ mstro_cdo_offer(mstro_cdo cdo)
 mstro_status
 mstro_cdo_withdraw_async(mstro_cdo cdo, mstro_request *request)
 {
+  MSTRO_API_NEEDS_INIT();
   if(cdo==NULL) {
     ERR("NULL CDO invalid\n");
     return MSTRO_INVARG;
@@ -1918,6 +1930,7 @@ mstro_cdo_withdraw_async(mstro_cdo cdo, mstro_request *request)
 mstro_status
 mstro_cdo_withdraw(mstro_cdo cdo)
 {
+  MSTRO_API_NEEDS_INIT();
   if(cdo==NULL) {
     ERR("NULL CDO invalid\n");
     return MSTRO_INVARG;
@@ -1958,6 +1971,7 @@ mstro_cdo_withdraw(mstro_cdo cdo)
 mstro_status
 mstro_cdo_require_async(mstro_cdo cdo, mstro_request *request)
 {
+  MSTRO_API_NEEDS_INIT();
   mstro_status status;
   if(cdo==NULL) {
     ERR("NULL CDO invalid\n");
@@ -2048,6 +2062,7 @@ mstro_cdo_require_async(mstro_cdo cdo, mstro_request *request)
 mstro_status
 mstro_cdo_require(mstro_cdo cdo)
 {
+  MSTRO_API_NEEDS_INIT();
   mstro_status status;
   if(cdo==NULL) {
     ERR("NULL CDO invalid\n");
@@ -2143,6 +2158,7 @@ mstro_cdo_require(mstro_cdo cdo)
 mstro_status
 mstro_cdo_demand(mstro_cdo cdo)
 {
+  MSTRO_API_NEEDS_INIT();
   if(cdo==NULL) {
     ERR("NULL CDO invalid\n");
     return MSTRO_INVARG;
@@ -2191,6 +2207,7 @@ mstro_cdo_demand(mstro_cdo cdo)
 mstro_status
 mstro_cdo_demand_async(mstro_cdo cdo, mstro_request *request)
 {
+  MSTRO_API_NEEDS_INIT();
   mstro_status status = MSTRO_UNIMPL;
 
   if(cdo==NULL) {
@@ -2249,6 +2266,7 @@ mstro_cdo_demand_async(mstro_cdo cdo, mstro_request *request)
 mstro_status
 mstro_cdo_retract_async(mstro_cdo cdo, mstro_request *request)
 {
+  MSTRO_API_NEEDS_INIT();
   if(cdo==NULL) {
     ERR("NULL CDO invalid\n");
     return MSTRO_INVARG;
@@ -2291,6 +2309,7 @@ mstro_cdo_retract_async(mstro_cdo cdo, mstro_request *request)
 mstro_status
 mstro_cdo_retract(mstro_cdo cdo)
 {
+  MSTRO_API_NEEDS_INIT();
   if(cdo==NULL) {
     ERR("NULL CDO invalid\n");
     return MSTRO_INVARG;
@@ -2327,8 +2346,9 @@ mstro_cdo_retract(mstro_cdo cdo)
   return status;
 }
 
+static inline
 mstro_status
-mstro_cdo_dispose_propagate(mstro_cdo cdo)
+mstro_cdo_dispose__propagate(mstro_cdo cdo)
 {
   if(cdo==NULL) {
     ERR("NULL CDO invalid\n");
@@ -2418,9 +2438,10 @@ mstro_cdo_dispose_propagate(mstro_cdo cdo)
 mstro_status
 mstro_cdo_dispose(mstro_cdo cdo)
 {
+  MSTRO_API_NEEDS_INIT();
   // Bookkeeping
   mstro_status s;
-  s = mstro_cdo_dispose_propagate(cdo);
+  s = mstro_cdo_dispose__propagate(cdo);
   if (s != MSTRO_OK && s != MSTRO_UNIMPL)
     // already printed an error
     return s;
@@ -2453,18 +2474,19 @@ mstro_cdo_dispose(mstro_cdo cdo)
 mstro_status
 mstro_cdo_dispose_and_reuse(mstro_cdo cdo)
 {
+  MSTRO_API_NEEDS_INIT();
   if(cdo==NULL) {
     ERR("NULL CDO invalid\n");
     return MSTRO_INVARG;
   }
   mstro_status s;
 
-  s = mstro_cdo_dispose_propagate(cdo); // will not free *cdo*
+  s = mstro_cdo_dispose__propagate(cdo); // will not free *cdo*
   if (s != MSTRO_OK && s != MSTRO_UNIMPL)
     // already printed an error
     return s;
 
-  s = mstro_cdo_declare_propagate(cdo->name, &cdo); // will not alloc *cdo*, will not alter user attributes
+  s = mstro_cdo_declare__propagate(cdo->name, &cdo); // will not alloc *cdo*, will not alter user attributes
   if (s != MSTRO_OK)
     // already printed an error
     return s;
diff --git a/maestro/status.c b/maestro/status.c
index a51683c5eb4ea4aa4d6e56bee1cdb56a9f08ef5f..219fcd2b29cf0ca4b8e5c576512110141cff41fb 100644
--- a/maestro/status.c
+++ b/maestro/status.c
@@ -40,6 +40,7 @@ static
 const char *g_mstro_status_names[] = {
   [MSTRO_OK]     = "success",
   [MSTRO_FAIL]   = "generic failure",
+  [MSTRO_UNINIT] = "maestro uninitialized -- you need to call mstro_init() first",
   [MSTRO_UNIMPL] = "unimplemented functionality",
   [MSTRO_INVARG] = "invalid argument",
   [MSTRO_INVOUT] = "invalid output argument pointer",