diff --git a/src/daqd/channel.hh b/src/daqd/channel.hh
index bf476aabd74be89945aa329df4309de23728b0db..e9488d4e30e6c7b8f4a003172d3c8708ab9e70c7 100644
--- a/src/daqd/channel.hh
+++ b/src/daqd/channel.hh
@@ -129,4 +129,27 @@ public:
     }
 };
 
+template < typename HashObject >
+void
+hash_channel( HashObject& hash, const channel_t& channel )
+{
+    hash.add( &( channel.chNum ), sizeof( channel.chNum ) );
+    hash.add( &( channel.seq_num ), sizeof( channel.seq_num ) );
+    size_t name_len = strnlen( channel.name, channel_t::channel_name_max_len );
+    hash.add( channel.name, name_len );
+    hash.add( &( channel.sample_rate ), sizeof( channel.sample_rate ) );
+    hash.add( &( channel.active ), sizeof( channel.active ) );
+    hash.add( &( channel.trend ), sizeof( channel.trend ) );
+    hash.add( &( channel.group_num ), sizeof( channel.group_num ) );
+    hash.add( &( channel.bps ), sizeof( channel.bps ) );
+    hash.add( &( channel.dcu_id ), sizeof( channel.dcu_id ) );
+    hash.add( &( channel.data_type ), sizeof( channel.data_type ) );
+    hash.add( &( channel.signal_gain ), sizeof( channel.signal_gain ) );
+    hash.add( &( channel.signal_slope ), sizeof( channel.signal_slope ) );
+    hash.add( &( channel.signal_offset ), sizeof( channel.signal_offset ) );
+    size_t unit_len =
+        strnlen( channel.signal_units, channel_t::engr_unit_max_len );
+    hash.add( channel.signal_units, unit_len );
+}
+
 #endif
diff --git a/src/daqd/daqd.cc b/src/daqd/daqd.cc
index 0d5126cfcaf8c69fe8beec8f115dca5b939b9201..61e198bf765b3580d4874b0aae5ec4e351ab165a 100644
--- a/src/daqd/daqd.cc
+++ b/src/daqd/daqd.cc
@@ -63,6 +63,7 @@ using namespace std;
 #include <string.h>
 
 #include "epics_pvs.hh"
+#include "checksum_crc32.hh"
 
 /// Helper function to deal with the archive channels.
 int
@@ -510,6 +511,7 @@ daqd_c::update_configuration_number( const char* source_address )
         check_sum.Update( &( cur->chNum ), sizeof( cur->chNum ) );
         check_sum.Update( &( cur->seq_num ), sizeof( cur->seq_num ) );
         size_t name_len = strnlen( cur->name, channel_t::channel_name_max_len );
+        static_assert( sizeof( name_len ) == 8, "not 4 bytes" );
         check_sum.Update( cur->name, sizeof( name_len ) );
         check_sum.Update( &( cur->sample_rate ), sizeof( cur->sample_rate ) );
         check_sum.Update( &( cur->active ), sizeof( cur->active ) );
@@ -1537,6 +1539,14 @@ daqd_c::start_main( int pmain_buffer_size, ostream* yyout )
     /* Epics display: memory buffer look back */
     PV::set_pv( PV::PV_LOOKBACK_RAM, main_buffer_size );
 
+    checksum_crc32   csum;
+    const channel_t* cur = channels;
+    const channel_t* end = cur + num_channels;
+    std::for_each( cur, end, [&csum]( const channel_t& channel ) {
+        hash_channel( csum, channel );
+    } );
+    PV::set_pv( PV::PV_CHANNEL_LIST_CHECK_SUM, csum.result( ) );
+
     return 0;
 }
 
diff --git a/src/daqd/epics_pvs.hh b/src/daqd/epics_pvs.hh
index 82ad739f4ad549f7f7067494d36c43cfb2754682..0544c69d6ff6fe6928ff8e3107985b609b37b1d5 100644
--- a/src/daqd/epics_pvs.hh
+++ b/src/daqd/epics_pvs.hh
@@ -40,6 +40,7 @@ namespace PV
         PV_SECOND_FRAME_SIZE,
         PV_MINUTE_FRAME_SIZE,
         PV_RETRANSMIT_TOTAL,
+        PV_CHANNEL_LIST_CHECK_SUM,
         // DCU counts
         PV_PRDCR_UNIQUE_DCU_REPORTED_PER_S,
         PV_PRDCR_TOTAL_DCU_REPORTED_PER_S,
diff --git a/src/daqd/exServer.cc b/src/daqd/exServer.cc
index 911b11d252c29fd57cb9f5f44287a85508b543b5..b53b26f91c050e4d1caed6fa60ad6850f5b8cbc8 100644
--- a/src/daqd/exServer.cc
+++ b/src/daqd/exServer.cc
@@ -227,6 +227,13 @@ pvInfo exServer::pvList[] = {
             excasIoSync,
             1,
             pvValue + PV::PV_RETRANSMIT_TOTAL ),
+    pvInfo( 1,
+            "CHANNEL_LIST_CHECK_SUM",
+            0xffffffff,
+            0,
+            excasIoSync,
+            1,
+            pvValue + PV::PV_CHANNEL_LIST_CHECK_SUM ),
     pvInfo( 1,
             "PRDCR_UNIQUE_DCU_REPORTED_PER_S",
             0xffffffff,