diff --git a/src/cntlr.c b/src/cntlr.c
index 42e4d7dce5389982fcf9981c52f01a7d83b5ee9c..d8b227b96677ac6855d574a6bee4dd699e384913 100644
--- a/src/cntlr.c
+++ b/src/cntlr.c
@@ -1784,6 +1784,33 @@ static void cntlr_signal_periodic_run(atimer_t *t)
 	timer_set(&c->signal_handler, 1 * 1000);
 }
 
+static void renew_nodes_configuration(struct controller *c)
+{
+	trace("%s: --->\n", __func__);
+	struct node *node = NULL;
+
+	/* When at least one running node was configured with older config, */
+	/* send autoconfig renew */
+	list_for_each_entry(node, &c->nodelist, list) {
+		if (!timestamp_invalid(&node->last_config) &&
+		    timestamp_less_than(&node->last_config, &c->cfg.last_change) &&
+		    timestamp_greater_than(&node->last_cmdu, &c->cfg.last_change)) {
+			uint8_t multicast_addr[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x13};
+			struct cmdu_buff *cmdu =
+				cntlr_gen_ap_autoconfig_renew(c, multicast_addr);
+
+			dbg("Found possibly unconfigured node: "MACFMT"\n", MAC2STR(node->alid));
+
+			if (cmdu) {
+				dbg("Sending AP_AUTOCONFIGURATION_RENEW\n");
+				send_cmdu(c, cmdu);
+				cmdu_free(cmdu);
+			}
+
+			break;
+		}
+	}
+}
 
 static void combined_link_metric_periodic_collection(struct controller *c)
 {
@@ -1888,6 +1915,7 @@ static void cntlr_periodic_run(atimer_t *t)
 
 	forall_node_get_sta_metrics(c);
 
+
 	/* TODO: */
 	//forall_node_get_usta_metrics(c);
 
@@ -1897,6 +1925,8 @@ static void cntlr_periodic_run(atimer_t *t)
 	/* Call AP metrics query and 1905 link metrics query for data collection */
 	combined_link_metric_periodic_collection(c);
 
+	renew_nodes_configuration(c);
+
 	timer_set(&c->heartbeat, 10 * 1000);
 }
 
diff --git a/src/cntlr.h b/src/cntlr.h
index 97adc8706f9bcd3219cae3bce891abfa03b2a4aa..ebe6e4249c2ba7b2811670e16380fce6566acf7f 100644
--- a/src/cntlr.h
+++ b/src/cntlr.h
@@ -276,6 +276,9 @@ struct node {
 	struct node_policy *np;
 	uint8_t ap_cap;
 	uint8_t map_profile;		   /** profile info of agent node */
+	struct timespec	last_config;       /** timestamp of most-recent config sent to agent */
+	struct timespec last_cmdu;         /** timestamp of last CMDU received from agent */
+
 	struct list_head radiolist;        /** list of netif_radio */
 	struct list_head stalist;
 	struct list_head list;
diff --git a/src/cntlr_map.c b/src/cntlr_map.c
index b473ff20bb4a1e4deb7c5fdef038126adaf0f607..53f6604f0e00c6afc704c456b2e289590031db64 100644
--- a/src/cntlr_map.c
+++ b/src/cntlr_map.c
@@ -1248,6 +1248,9 @@ int handle_ap_autoconfig_wsc(void *cntlr, struct cmdu_buff *rx_cmdu,
 
 	cmdu_free(cmdu);
 
+	n->last_config = c->cfg.last_change;
+
+
 	np = agent_find_policy(c, rx_cmdu->origin);
 	if (!np) {
 		dbg("|%s:%d| missing node policy for node almac:" MACFMT \
@@ -4071,6 +4074,12 @@ int cntlr_handle_map_event(void *module, uint16_t cmdutype, uint16_t mid,
 	if (f[idx].debug)
 		ret = f[idx].debug(c, cmdu, n);
 
+	if (!n)
+		n = cntlr_find_node(c, origin);
+
+	if (n)
+		timestamp_update(&n->last_cmdu);
+
 	//TODO: check ret
 
 	cmdu_free(cmdu);
diff --git a/src/config.c b/src/config.c
index 078657f338eb13a27d99a8c277cf5f9b10e4a15e..319135d70f66bf3295a1769f0ae628cd5d09073b 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1862,6 +1862,10 @@ uint8_t cntlr_config_reload(struct controller_config *cfg)
 	/* get bitmap of what sections changed */
 	diff = cntlr_config_diff(cfg, &old);
 
+	if (diff & CONFIG_DIFF_CREDENTIALS || diff & CONFIG_DIFF_VLAN)
+		timestamp_update(&cfg->last_change);
+
+
 	/* clean old lists */
 	clean_cred_list(&old);
 	clean_agent_policies(&old); /* cleans nodelist */
diff --git a/src/config.h b/src/config.h
index c81dffe698619dcd987b8da8353d21c5b5b01175..6f4d09190d239d25cf57e6ffbc33795bffa2ac0d 100644
--- a/src/config.h
+++ b/src/config.h
@@ -238,6 +238,7 @@ struct controller_config {
 	struct list_head dpp_cntlrlist;
 	struct qos_control_config qos;
 #endif
+	struct timespec	last_change;		/* timestamp of most recent config change */
 };
 
 struct controller;