diff --git a/slurm/slurm.h.in b/slurm/slurm.h.in
index a814de1e6f68882f8fa793aab729af673e648b2c..18cdae85e3b5edcda6801bce38074de0cc99eab1 100644
--- a/slurm/slurm.h.in
+++ b/slurm/slurm.h.in
@@ -1349,7 +1349,9 @@ typedef struct node_info {
 				 * the node */
 	char *features;		/* list of a node's features */
 	char *gres;		/* list of a node's generic resources */
-	char *name;		/* node name */
+	char *name;		/* node name to slurm */
+	char *node_addr;	/* communication name (optional) */
+	char *node_hostname;	/* node's hostname (optional) */
 	uint16_t node_state;	/* see enum node_states */
 	char *os;		/* operating system currently running */
 	uint32_t real_memory;	/* configured MB of real memory on the node */
diff --git a/src/api/node_info.c b/src/api/node_info.c
index 4de673136044c7f5c64b5f078d129e8ac511888f..5d79fa8986bc4c7da502e05e895c0ba1bb7554cb 100644
--- a/src/api/node_info.c
+++ b/src/api/node_info.c
@@ -177,7 +177,7 @@ slurm_sprint_node_table (node_info_t * node_ptr,
 	/****** Line 1 ******/
 	snprintf(tmp_line, sizeof(tmp_line), "NodeName=%s ", node_ptr->name);
 	xstrcat(out, tmp_line);
-	if (node_ptr->arch ) {
+	if (node_ptr->arch) {
 		snprintf(tmp_line, sizeof(tmp_line), "Arch=%s ",
 			 node_ptr->arch);
 		xstrcat(out, tmp_line);
@@ -208,7 +208,19 @@ slurm_sprint_node_table (node_info_t * node_ptr,
 	else
 		xstrcat(out, "\n   ");
 
-	/****** Line 4 ******/
+	/****** Line 4 (optional) ******/
+	if (node_ptr->node_hostname || node_ptr->node_addr) {
+		snprintf(tmp_line, sizeof(tmp_line),
+			 "NodeAddr=%s NodeHostName=%s",
+			 node_ptr->node_addr, node_ptr->node_hostname);
+		xstrcat(out, tmp_line);	
+		if (one_liner)
+			xstrcat(out, " ");
+		else
+			xstrcat(out, "\n   ");
+	}
+
+	/****** Line 5 ******/
 	if (node_ptr->os) {
 		snprintf(tmp_line, sizeof(tmp_line), "OS=%s ", node_ptr->os);
 		xstrcat(out, tmp_line);
@@ -221,7 +233,7 @@ slurm_sprint_node_table (node_info_t * node_ptr,
 	else
 		xstrcat(out, "\n   ");
 
-	/****** Line 5 ******/
+	/****** Line 6 ******/
 
 	snprintf(tmp_line, sizeof(tmp_line),
 		 "State=%s%s%s%s ThreadsPerCore=%u TmpDisk=%u Weight=%u",
@@ -233,7 +245,7 @@ slurm_sprint_node_table (node_info_t * node_ptr,
 	else
 		xstrcat(out, "\n   ");
 
-	/****** Line 6 ******/
+	/****** Line 7 ******/
 	if (node_ptr->boot_time) {
 		slurm_make_time_str ((time_t *)&node_ptr->boot_time,
 				     time_str, sizeof(time_str));
@@ -256,7 +268,7 @@ slurm_sprint_node_table (node_info_t * node_ptr,
 	else
 		xstrcat(out, "\n   ");
 
-	/****** Line 7 ******/
+	/****** Line 8 ******/
 	if (node_ptr->reason_time) {
 		char *user_name = uid_to_string(node_ptr->reason_uid);
 		slurm_make_time_str ((time_t *)&node_ptr->reason_time,
diff --git a/src/common/node_conf.c b/src/common/node_conf.c
index 3d517b6176e30bb7994b98e0adf473572870bf4c..5d6c3fce172bef439c7eb63639eeab42c00d1a01 100644
--- a/src/common/node_conf.c
+++ b/src/common/node_conf.c
@@ -150,6 +150,7 @@ static int _build_single_nodeline_info(slurm_conf_node_t *node_ptr,
 	char *hostname = NULL;
 	char *address = NULL;
 	int state_val = NODE_STATE_UNKNOWN;
+	int address_count, alias_count, hostname_count;
 
 	if (node_ptr->state != NULL) {
 		state_val = state_str2int(node_ptr->state, node_ptr->nodenames);
@@ -177,22 +178,27 @@ static int _build_single_nodeline_info(slurm_conf_node_t *node_ptr,
 	}
 
 	/* some sanity checks */
+	address_count  = hostlist_count(address_list);
+	alias_count    = hostlist_count(alias_list);
+	hostname_count = hostlist_count(hostname_list);
 #ifdef HAVE_FRONT_END
-	if ((hostlist_count(hostname_list) > 1) ||
-	    (hostlist_count(address_list)  > 1)) {
-		error("Only one NodeHostName and NodeAddr are allowed "
-		      "in FRONT_END mode");
+	if ((hostname_count != alias_count) && (hostname_count != 1)) {
+		error("NodeHostname count must equal that of NodeName "
+		      "records of there must be no more than one");
+		goto cleanup;
+	}
+	if ((address_count != alias_count) && (address_count != 1)) {
+		error("NodeAddr count must equal that of NodeName "
+		      "records of there must be no more than one");
 		goto cleanup;
 	}
-	hostname = node_ptr->hostnames;
-	address = node_ptr->addresses;
 #else
-	if (hostlist_count(hostname_list) < hostlist_count(alias_list)) {
+	if (hostname_count < alias_count) {
 		error("At least as many NodeHostname are required "
 		      "as NodeName");
 		goto cleanup;
 	}
-	if (hostlist_count(address_list) < hostlist_count(alias_list)) {
+	if (address_count < alias_count) {
 		error("At least as many NodeAddr are required as NodeName");
 		goto cleanup;
 	}
@@ -200,10 +206,10 @@ static int _build_single_nodeline_info(slurm_conf_node_t *node_ptr,
 
 	/* now build the individual node structures */
 	while ((alias = hostlist_shift(alias_list))) {
-#ifndef HAVE_FRONT_END
-		hostname = hostlist_shift(hostname_list);
-		address = hostlist_shift(address_list);
-#endif
+		if (hostname_count)
+			hostname = hostlist_shift(hostname_list);
+		if (address_count)
+			address = hostlist_shift(address_list);
 		/* find_node_record locks this to get the
 		 * alias so we need to unlock */
 		node_rec = find_node_record(alias);
@@ -215,6 +221,7 @@ static int _build_single_nodeline_info(slurm_conf_node_t *node_ptr,
 				node_rec->node_state = state_val;
 			node_rec->last_response = (time_t) 0;
 			node_rec->comm_name = xstrdup(address);
+			node_rec->node_hostname = xstrdup(hostname);
 			node_rec->port      = node_ptr->port;
 			node_rec->weight    = node_ptr->weight;
 			node_rec->features  = xstrdup(node_ptr->feature);
@@ -224,10 +231,10 @@ static int _build_single_nodeline_info(slurm_conf_node_t *node_ptr,
 			error("reconfiguration for node %s, ignoring!", alias);
 		}
 		free(alias);
-#ifndef HAVE_FRONT_END
-		free(hostname);
-		free(address);
-#endif
+		if (hostname_count--)
+			free(hostname);
+		if (address_count--)
+			free(address);
 	}
 
 	/* free allocated storage */
@@ -881,6 +888,7 @@ extern void purge_node_rec (struct node_record *node_ptr)
 	if (node_ptr->gres_list)
 		list_destroy(node_ptr->gres_list);
 	xfree(node_ptr->name);
+	xfree(node_ptr->node_hostname);
 	xfree(node_ptr->os);
 	xfree(node_ptr->part_pptr);
 	xfree(node_ptr->reason);
diff --git a/src/common/node_conf.h b/src/common/node_conf.h
index 927a03ae292ebb0cd3ebdfba17247c333cae1151..7b50ba470a7783a3ae2fe904a383e6051e901520 100644
--- a/src/common/node_conf.h
+++ b/src/common/node_conf.h
@@ -93,6 +93,7 @@ extern List feature_list;	/* list of features_record entries */
 struct node_record {
 	uint32_t magic;			/* magic cookie for data integrity */
 	char *name;			/* name of the node. NULL==defunct */
+	char *node_hostname;		/* hostname of the node */
 	uint16_t node_state;		/* enum node_states, ORed with
 					 * NODE_STATE_NO_RESPOND if not
 					 * responding */
diff --git a/src/common/read_config.c b/src/common/read_config.c
index 1dc532d30cf5259cd1411b8ad0f1c2588bb0fe9e..666ce2aed1f1866b586a1c1c38790e776d2af013 100644
--- a/src/common/read_config.c
+++ b/src/common/read_config.c
@@ -545,21 +545,10 @@ static int _parse_nodename(void **dest, slurm_parser_enum_t type,
 			_set_node_prefix(n->nodenames);
 #endif
 
-#ifdef HAVE_FRONT_END
-		if (!s_p_get_string(&n->hostnames, "NodeHostname", tbl))
-			xfree(n->hostnames);
-		if (!s_p_get_string(&n->addresses, "NodeAddr", tbl))
-			xfree(n->addresses);
-		else {
-			verbose("Use FrontendNode/FrondendAddr configuration "
-				"options instead of NodeAddr");
-		}
-#else
 		if (!s_p_get_string(&n->hostnames, "NodeHostname", tbl))
 			n->hostnames = xstrdup(n->nodenames);
 		if (!s_p_get_string(&n->addresses, "NodeAddr", tbl))
 			n->addresses = xstrdup(n->hostnames);
-#endif
 
 		if (!s_p_get_uint16(&n->cores, "CoresPerSocket", tbl)
 		    && !s_p_get_uint16(&n->cores, "CoresPerSocket", dflt)) {
@@ -1080,7 +1069,7 @@ extern int slurm_conf_downnodes_array(slurm_conf_downnodes_t **ptr_array[])
 	}
 }
 
-static void _free_name_hashtbl()
+static void _free_name_hashtbl(void)
 {
 	int i;
 	names_ll_t *p, *q;
@@ -1101,7 +1090,7 @@ static void _free_name_hashtbl()
 	nodehash_initialized = false;
 }
 
-static void _init_name_hashtbl()
+static void _init_name_hashtbl(void)
 {
 	return;
 }
@@ -1154,7 +1143,7 @@ static void _push_to_hashtbls(char *alias, char *hostname,
 	}
 
 	/* Create the new data structure and link it into the hash tables */
-	new = (names_ll_t *)xmalloc(sizeof(*new));
+	new = (names_ll_t *)xmalloc(sizeof(names_ll_t));
 	new->alias	= xstrdup(alias);
 	new->hostname	= xstrdup(hostname);
 	new->address	= xstrdup(address);
@@ -1201,6 +1190,7 @@ static int _register_conf_node_aliases(slurm_conf_node_t *node_ptr)
 	char *hostname = NULL;
 	char *address = NULL;
 	int error_code = SLURM_SUCCESS;
+	int address_count, alias_count, hostname_count;
 
 	if ((node_ptr->nodenames == NULL) || (node_ptr->nodenames[0] == '\0'))
 		return -1;
@@ -1230,24 +1220,27 @@ static int _register_conf_node_aliases(slurm_conf_node_t *node_ptr)
 #endif
 
 	/* some sanity checks */
+	address_count  = hostlist_count(address_list);
+	alias_count    = hostlist_count(alias_list);
+	hostname_count = hostlist_count(hostname_list);
 #ifdef HAVE_FRONT_END
-	if ((hostlist_count(hostname_list) > 1) ||
-	    (hostlist_count(address_list)  > 1)) {
-		error("Only one NodeHostName and NodeAddr allowed "
-		      "in FRONT_END mode");
-		error("Use FrontendNode/FrondendAddr configuration options");
+	if ((hostname_count != alias_count) && (hostname_count != 1)) {
+		error("NodeHostname count must equal that of NodeName "
+		      "records of there must be no more than one");
+		goto cleanup;
+	}
+	if ((address_count != alias_count) && (address_count != 1)) {
+		error("NodeAddr count must equal that of NodeName "
+		      "records of there must be no more than one");
 		goto cleanup;
 	}
-
-	hostname = node_ptr->hostnames;
-	address = node_ptr->addresses;
 #else
-	if (hostlist_count(hostname_list) < hostlist_count(alias_list)) {
+	if (hostname_count < alias_count) {
 		error("At least as many NodeHostname are required "
 		      "as NodeName");
 		goto cleanup;
 	}
-	if (hostlist_count(address_list) < hostlist_count(alias_list)) {
+	if (address_count < alias_count) {
 		error("At least as many NodeAddr are required as NodeName");
 		goto cleanup;
 	}
@@ -1255,20 +1248,18 @@ static int _register_conf_node_aliases(slurm_conf_node_t *node_ptr)
 
 	/* now build the individual node structures */
 	while ((alias = hostlist_shift(alias_list))) {
-#ifndef HAVE_FRONT_END
-		hostname = hostlist_shift(hostname_list);
-		address = hostlist_shift(address_list);
-#endif
+		if (hostname_count)
+			hostname = hostlist_shift(hostname_list);
+		if (address_count)
+			address = hostlist_shift(address_list);
 		_push_to_hashtbls(alias, hostname, address, node_ptr->port,
 				  node_ptr->cpus, node_ptr->sockets,
 				  node_ptr->cores, node_ptr->threads);
-
 		free(alias);
-#ifndef HAVE_FRONT_END
-		free(hostname);
-		free(address);
-#endif
-
+		if (hostname_count--)
+			free(hostname);
+		if (address_count--)
+			free(address);
 	}
 
 	/* free allocated storage */
diff --git a/src/common/slurm_protocol_defs.c b/src/common/slurm_protocol_defs.c
index e99ccdf3d76553a514037f09e564f0fd53a7b572..996c521d8e4400c37037a541aed7f1c99f2e20ff 100644
--- a/src/common/slurm_protocol_defs.c
+++ b/src/common/slurm_protocol_defs.c
@@ -1861,9 +1861,11 @@ static void _free_all_node_info(node_info_msg_t *msg)
 void slurm_free_node_info_members(node_info_t * node)
 {
 	if (node) {
-		xfree(node->name);
 		xfree(node->arch);
 		xfree(node->features);
+		xfree(node->name);
+		xfree(node->node_hostname);
+		xfree(node->node_addr);
 		xfree(node->os);
 		xfree(node->reason);
 		select_g_select_nodeinfo_free(node->select_nodeinfo);
diff --git a/src/common/slurm_protocol_pack.c b/src/common/slurm_protocol_pack.c
index bf3ce13be50d2636f499f835fcf162e5a6d28919..effab78202284de0009dce919a87127ced570360 100644
--- a/src/common/slurm_protocol_pack.c
+++ b/src/common/slurm_protocol_pack.c
@@ -2642,7 +2642,35 @@ _unpack_node_info_members(node_info_t * node, Buf buffer,
 
 	xassert(node != NULL);
 
-	if (protocol_version >= SLURM_2_2_PROTOCOL_VERSION) {
+	if (protocol_version >= SLURM_2_3_PROTOCOL_VERSION) {
+		safe_unpackstr_xmalloc(&node->name, &uint32_tmp, buffer);
+		safe_unpackstr_xmalloc(&node->node_hostname, &uint32_tmp,
+				       buffer);
+		safe_unpackstr_xmalloc(&node->node_addr, &uint32_tmp, buffer);
+		safe_unpack16(&node->node_state, buffer);
+		safe_unpack16(&node->cpus, buffer);
+		safe_unpack16(&node->sockets, buffer);
+		safe_unpack16(&node->cores, buffer);
+		safe_unpack16(&node->threads, buffer);
+
+		safe_unpack32(&node->real_memory, buffer);
+		safe_unpack32(&node->tmp_disk, buffer);
+		safe_unpack32(&node->weight, buffer);
+		safe_unpack32(&node->reason_uid, buffer);
+
+		safe_unpack_time(&node->boot_time, buffer);
+		safe_unpack_time(&node->reason_time, buffer);
+		safe_unpack_time(&node->slurmd_start_time, buffer);
+
+		select_g_select_nodeinfo_unpack(&node->select_nodeinfo, buffer,
+						protocol_version);
+
+		safe_unpackstr_xmalloc(&node->arch, &uint32_tmp, buffer);
+		safe_unpackstr_xmalloc(&node->features, &uint32_tmp, buffer);
+		safe_unpackstr_xmalloc(&node->gres, &uint32_tmp, buffer);
+		safe_unpackstr_xmalloc(&node->os, &uint32_tmp, buffer);
+		safe_unpackstr_xmalloc(&node->reason, &uint32_tmp, buffer);
+	} else if (protocol_version >= SLURM_2_2_PROTOCOL_VERSION) {
 		safe_unpackstr_xmalloc(&node->name, &uint32_tmp, buffer);
 		safe_unpack16(&node->node_state, buffer);
 		safe_unpack16(&node->cpus, buffer);
diff --git a/src/slurmctld/node_mgr.c b/src/slurmctld/node_mgr.c
index 09361c4f6859a300c98b71600b31f4b9ae995b42..440c97dd018d5aa698d9452cc054a83068bc9b70 100644
--- a/src/slurmctld/node_mgr.c
+++ b/src/slurmctld/node_mgr.c
@@ -642,8 +642,10 @@ extern void pack_all_node (char **buffer_ptr, int *buffer_size,
 static void _pack_node (struct node_record *dump_node_ptr, Buf buffer,
 			uint16_t protocol_version)
 {
-	if(protocol_version >= SLURM_2_2_PROTOCOL_VERSION) {
+	if (protocol_version >= SLURM_2_3_PROTOCOL_VERSION) {
 		packstr (dump_node_ptr->name, buffer);
+		packstr (dump_node_ptr->node_hostname, buffer);
+		packstr (dump_node_ptr->comm_name, buffer);
 		pack16  (dump_node_ptr->node_state, buffer);
 		if (slurmctld_conf.fast_schedule) {
 			/* Only data from config_record used for scheduling */
@@ -680,7 +682,45 @@ static void _pack_node (struct node_record *dump_node_ptr, Buf buffer,
 			packstr(dump_node_ptr->config_ptr->gres, buffer);
 		packstr(dump_node_ptr->os, buffer);
 		packstr(dump_node_ptr->reason, buffer);
-	} else if(protocol_version >= SLURM_2_1_PROTOCOL_VERSION) {
+	} else if (protocol_version >= SLURM_2_2_PROTOCOL_VERSION) {
+		packstr (dump_node_ptr->name, buffer);
+		pack16  (dump_node_ptr->node_state, buffer);
+		if (slurmctld_conf.fast_schedule) {
+			/* Only data from config_record used for scheduling */
+			pack16(dump_node_ptr->config_ptr->cpus, buffer);
+			pack16(dump_node_ptr->config_ptr->sockets, buffer);
+			pack16(dump_node_ptr->config_ptr->cores, buffer);
+			pack16(dump_node_ptr->config_ptr->threads, buffer);
+			pack32(dump_node_ptr->config_ptr->real_memory, buffer);
+			pack32(dump_node_ptr->config_ptr->tmp_disk, buffer);
+		} else {
+			/* Individual node data used for scheduling */
+			pack16(dump_node_ptr->cpus, buffer);
+			pack16(dump_node_ptr->sockets, buffer);
+			pack16(dump_node_ptr->cores, buffer);
+			pack16(dump_node_ptr->threads, buffer);
+			pack32(dump_node_ptr->real_memory, buffer);
+			pack32(dump_node_ptr->tmp_disk, buffer);
+		}
+		pack32(dump_node_ptr->config_ptr->weight, buffer);
+		pack32(dump_node_ptr->reason_uid, buffer);
+
+		pack_time(dump_node_ptr->boot_time, buffer);
+		pack_time(dump_node_ptr->reason_time, buffer);
+		pack_time(dump_node_ptr->slurmd_start_time, buffer);
+
+		select_g_select_nodeinfo_pack(dump_node_ptr->select_nodeinfo,
+					      buffer, protocol_version);
+
+		packstr(dump_node_ptr->arch, buffer);
+		packstr(dump_node_ptr->features, buffer);
+		if (dump_node_ptr->gres)
+			packstr(dump_node_ptr->gres, buffer);
+		else
+			packstr(dump_node_ptr->config_ptr->gres, buffer);
+		packstr(dump_node_ptr->os, buffer);
+		packstr(dump_node_ptr->reason, buffer);
+	} else if (protocol_version >= SLURM_2_1_PROTOCOL_VERSION) {
 		packstr (dump_node_ptr->name, buffer);
 		pack16  (dump_node_ptr->node_state, buffer);
 		if (slurmctld_conf.fast_schedule) {
diff --git a/src/sview/node_info.c b/src/sview/node_info.c
index 3fb5a99c6cdc9cb760a2935608c4fba984ab1e2e..3410d6f3b6f1392c1ab39fa4f61b8e713267f5d2 100644
--- a/src/sview/node_info.c
+++ b/src/sview/node_info.c
@@ -51,6 +51,8 @@ enum {
 	SORTID_GRES,
 	SORTID_MEMORY,
 	SORTID_NAME,
+	SORTID_NODE_ADDR,
+	SORTID_NODE_HOSTNAME,
 	SORTID_REASON,
 	SORTID_SLURMD_START_TIME,
 	SORTID_SOCKETS,
@@ -80,6 +82,10 @@ static display_data_t display_data_node[] = {
 	 create_model_node, admin_edit_node},
 	{G_TYPE_STRING, SORTID_NAME, "Name", FALSE, EDIT_NONE, refresh_node,
 	 create_model_node, admin_edit_node},
+	{G_TYPE_STRING, SORTID_NODE_ADDR, "NodeAddr", FALSE, EDIT_NONE,
+	 refresh_node, create_model_node, admin_edit_node},
+	{G_TYPE_STRING, SORTID_NODE_HOSTNAME, "NodeHostName", FALSE, EDIT_NONE,
+	 refresh_node, create_model_node, admin_edit_node},
 	{G_TYPE_STRING, SORTID_COLOR, NULL, TRUE, EDIT_COLOR, refresh_node,
 	 create_model_node, admin_edit_node},
 	{G_TYPE_STRING, SORTID_STATE, "State", FALSE, EDIT_MODEL, refresh_node,
@@ -171,6 +177,16 @@ static void _layout_node_record(GtkTreeView *treeview,
 						 SORTID_NAME),
 				   node_ptr->name);
 
+	add_display_treestore_line(update, treestore, &iter,
+				   find_col_name(display_data_node,
+						 SORTID_NODE_ADDR),
+				   node_ptr->node_addr);
+
+	add_display_treestore_line(update, treestore, &iter,
+				   find_col_name(display_data_node,
+						 SORTID_NODE_HOSTNAME),
+				   node_ptr->node_hostname);
+
 	convert_num_unit((float)node_ptr->cpus, tmp_cnt, sizeof(tmp_cnt),
 			 UNIT_NONE);
 	add_display_treestore_line(update, treestore, &iter,
@@ -299,6 +315,10 @@ static void _update_node_record(sview_node_info_t *sview_node_info_ptr,
 					% sview_colors_cnt], -1);
 
 	gtk_tree_store_set(treestore, iter, SORTID_NAME, node_ptr->name, -1);
+	gtk_tree_store_set(treestore, iter, SORTID_NODE_ADDR,
+			   node_ptr->node_addr, -1);
+	gtk_tree_store_set(treestore, iter, SORTID_NODE_HOSTNAME,
+			   node_ptr->node_hostname, -1);
 
 	gtk_tree_store_set(treestore, iter, SORTID_STATE_NUM,
 			   node_ptr->node_state, -1);
diff --git a/testsuite/expect/test2.8 b/testsuite/expect/test2.8
index 2948650f75ff33540feba2e5530aef0ad5afb380..91ba33aa63a7124fe5a090b4dfcbc9e4d3c58973 100755
--- a/testsuite/expect/test2.8
+++ b/testsuite/expect/test2.8
@@ -119,7 +119,7 @@ expect {
 	}
 }
 if {$matches != 2} {
-	send_user "\nFAILURE: scontrol failed to find all jobs\n"
+	send_user "\nFAILURE: scontrol found $matches of 2 jobs\n"
 	set exit_code 1
 }