diff --git a/CMakeLists.txt b/CMakeLists.txt
index c0d517c5e4..b55a26438d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1068,6 +1068,8 @@ set(LIBNETDATA_FILES
         src/libnetdata/os/mmap_limit.h
         src/libnetdata/signals/signals.c
         src/libnetdata/signals/signals.h
+        src/libnetdata/os/machine_id.c
+        src/libnetdata/os/machine_id.h
 )
 
 list(APPEND LIBNETDATA_FILES ${INICFG_FILES})
diff --git a/src/daemon/daemon-shutdown.c b/src/daemon/daemon-shutdown.c
index bd44e71545..7e75a1f1a8 100644
--- a/src/daemon/daemon-shutdown.c
+++ b/src/daemon/daemon-shutdown.c
@@ -300,13 +300,16 @@ void netdata_cleanup_and_exit(EXIT_REASON reason, const char *action, const char
     sqlite_close_databases();
     watcher_step_complete(WATCHER_STEP_ID_CLOSE_SQL_DATABASES);
     sqlite_library_shutdown();
-
-
+    
     // unlink the pid
-    if(pidfile && *pidfile) {
-        if(unlink(pidfile) != 0)
-            netdata_log_error("EXIT: cannot unlink pidfile '%s'.", pidfile);
-    }
+    if(pidfile && *pidfile && unlink(pidfile) != 0)
+        netdata_log_error("EXIT: cannot unlink pidfile '%s'.", pidfile);
+
+    // unlink the pipe
+    const char *pipe = daemon_pipename();
+    if(pipe && *pipe && unlink(pipe) != 0)
+        netdata_log_error("EXIT: cannot unlink netdatacli socket file '%s'.", pipe);
+
     watcher_step_complete(WATCHER_STEP_ID_REMOVE_PID_FILE);
 
     netdata_ssl_cleanup();
diff --git a/src/daemon/daemon-status-file.c b/src/daemon/daemon-status-file.c
index f7a54f7845..c19be8053f 100644
--- a/src/daemon/daemon-status-file.c
+++ b/src/daemon/daemon-status-file.c
@@ -9,7 +9,7 @@
 #include <openssl/pem.h>
 #include <openssl/err.h>
 
-#define STATUS_FILE_VERSION 9
+#define STATUS_FILE_VERSION 10
 
 #define STATUS_FILENAME "status-netdata.json"
 
@@ -129,6 +129,7 @@ static void daemon_status_file_to_json(BUFFER *wb, DAEMON_STATUS_FILE *ds) {
 
     buffer_json_member_add_object(wb, "host"); // ECS
     {
+        buffer_json_member_add_uuid_compact(wb, "id", ds->machine_id.uuid);
         buffer_json_member_add_string_or_empty(wb, "architecture", ds->architecture); // ECS
         buffer_json_member_add_string_or_empty(wb, "virtualization", ds->virtualization); // custom
         buffer_json_member_add_string_or_empty(wb, "container", ds->container); // custom
@@ -136,7 +137,7 @@ static void daemon_status_file_to_json(BUFFER *wb, DAEMON_STATUS_FILE *ds) {
 
         buffer_json_member_add_object(wb, "boot"); // ECS
         {
-            buffer_json_member_add_uuid(wb, "id", ds->boot_id.uuid); // ECS
+            buffer_json_member_add_uuid_compact(wb, "id", ds->boot_id.uuid); // ECS
         }
         buffer_json_object_close(wb);
 
@@ -224,6 +225,7 @@ static bool daemon_status_file_from_json(json_object *jobj, void *data, BUFFER *
     bool required_v3 = version >= 3 ? strict : false;
     bool required_v4 = version >= 4 ? strict : false;
     bool required_v5 = version >= 5 ? strict : false;
+    bool required_v10 = version >= 10 ? strict : false;
 
     // Parse timestamp
     JSONC_PARSE_TXT2CHAR_OR_ERROR_AND_RETURN(jobj, path, "@timestamp", datetime, error, required_v1);
@@ -254,6 +256,7 @@ static bool daemon_status_file_from_json(json_object *jobj, void *data, BUFFER *
 
     // Parse host object
     JSONC_PARSE_SUBOBJECT(jobj, path, "host", error, required_v1, {
+        JSONC_PARSE_TXT2UUID_OR_ERROR_AND_RETURN(jobj, path, "id", ds->machine_id.uuid, error, required_v10);
         JSONC_PARSE_TXT2CHAR_OR_ERROR_AND_RETURN(jobj, path, "architecture", ds->architecture, error, required_v1);
         JSONC_PARSE_TXT2CHAR_OR_ERROR_AND_RETURN(jobj, path, "virtualization", ds->virtualization, error, required_v1);
         JSONC_PARSE_TXT2CHAR_OR_ERROR_AND_RETURN(jobj, path, "container", ds->container, error, required_v1);
@@ -399,6 +402,9 @@ static void daemon_status_file_refresh(DAEMON_STATUS status) {
             session_status.host_id = UUID_ZERO;
     }
 
+    if(UUIDiszero(session_status.machine_id))
+        session_status.machine_id = os_machine_id();
+
     // copy items from the old status if they are not set
     if(UUIDiszero(session_status.claim_id))
         session_status.claim_id = last_session_status.claim_id;
diff --git a/src/daemon/daemon-status-file.h b/src/daemon/daemon-status-file.h
index d2b4261267..c9f6133510 100644
--- a/src/daemon/daemon-status-file.h
+++ b/src/daemon/daemon-status-file.h
@@ -44,6 +44,7 @@ typedef struct daemon_status_file {
     ND_UUID host_id;            // the machine guid of the agent
     ND_UUID node_id;            // the Netdata Cloud node id of the agent
     ND_UUID claim_id;           // the Netdata Cloud claim id of the agent
+    ND_UUID machine_id;         // the unique machine id of the system
 
     struct {
         usec_t init_started_ut;
diff --git a/src/daemon/main.c b/src/daemon/main.c
index 7e371d5798..8e3c2051b7 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -902,6 +902,7 @@ int netdata_main(int argc, char **argv) {
 
     delta_startup_time("web server sockets");
     if(web_server_mode != WEB_SERVER_MODE_NONE) {
+        errno_clear();
         if (!api_listen_sockets_setup()) {
             exit_initiated_add(EXIT_REASON_ALREADY_RUNNING);
             daemon_status_file_update_status(DAEMON_STATUS_NONE);
diff --git a/src/libnetdata/os/machine_id.c b/src/libnetdata/os/machine_id.c
new file mode 100644
index 0000000000..ca2ecabfd1
--- /dev/null
+++ b/src/libnetdata/os/machine_id.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "machine_id.h"
+#include "libnetdata/libnetdata.h"
+
+static ND_UUID cached_machine_id = { 0 };
+static SPINLOCK spinlock = SPINLOCK_INITIALIZER;
+
+#if defined(OS_LINUX)
+
+static ND_UUID get_machine_id(void) {
+    ND_UUID machine_id = { 0 };
+
+    // Try systemd machine-id locations first
+    const char *locations[] = {
+        "/etc/machine-id",                  // systemd standard location
+        "/var/lib/dbus/machine-id",         // fallback for older systems or different distros
+        "/sys/class/dmi/id/product_uuid"    // hardware-based UUID from DMI
+    };
+
+    for (size_t i = 0; i < _countof(locations); i++) {
+        char filename[FILENAME_MAX + 1];
+        snprintfz(filename, sizeof(filename), "%s%s",
+                  netdata_configured_host_prefix ? netdata_configured_host_prefix : "", locations[i]);
+
+        char buf[128];
+        if (read_txt_file(filename, buf, sizeof(buf)) == 0) {
+            if (uuid_parse(trim(buf), machine_id.uuid) == 0)
+                return machine_id;
+        }
+    }
+
+    // If no reliable machine ID could be found, return NO_MACHINE_ID
+    return NO_MACHINE_ID;
+}
+
+#elif defined(OS_FREEBSD)
+
+static ND_UUID get_machine_id(void) {
+    ND_UUID machine_id = { 0 };
+    char buf[128];
+
+    // Try FreeBSD host ID first
+    char filename[FILENAME_MAX + 1];
+    snprintfz(filename, sizeof(filename), "%s/etc/hostid",
+              netdata_configured_host_prefix ? netdata_configured_host_prefix : "");
+
+    if (read_txt_file(filename, buf, sizeof(buf)) == 0) {
+        if (uuid_parse(trim(buf), machine_id.uuid) == 0)
+            return machine_id;
+    }
+
+    // Fallback: Read system kern.hostuuid sysctl
+    size_t len = sizeof(buf);
+    if (sysctlbyname("kern.hostuuid", buf, &len, NULL, 0) == 0) {
+        if (uuid_parse(trim(buf), machine_id.uuid) == 0)
+            return machine_id;
+    }
+
+    // If no reliable machine ID could be found, return NO_MACHINE_ID
+    return NO_MACHINE_ID;
+}
+
+#elif defined(OS_MACOS)
+
+#include <IOKit/IOKitLib.h>
+
+static ND_UUID get_machine_id(void) {
+    ND_UUID machine_id = { 0 };
+
+    // First try to get the platform UUID
+    io_registry_entry_t ioRegistryRoot = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/");
+    if (ioRegistryRoot) {
+        CFStringRef uuidCf = (CFStringRef) IORegistryEntryCreateCFProperty(
+            ioRegistryRoot,
+            CFSTR(kIOPlatformUUIDKey),
+            kCFAllocatorDefault,
+            0);
+
+        if (uuidCf) {
+            char uuid_str[UUID_STR_LEN];
+            if (CFStringGetCString(uuidCf, uuid_str, sizeof(uuid_str), kCFStringEncodingUTF8)) {
+                if (uuid_parse(uuid_str, machine_id.uuid) == 0) {
+                    CFRelease(uuidCf);
+                    IOObjectRelease(ioRegistryRoot);
+                    return machine_id;
+                }
+            }
+            CFRelease(uuidCf);
+        }
+        IOObjectRelease(ioRegistryRoot);
+    }
+
+    // Fallback to IOPlatformExpertDevice's IOPlatformSerialNumber
+    io_service_t platformExpert = IOServiceGetMatchingService(
+        kIOMasterPortDefault,
+        IOServiceMatching("IOPlatformExpertDevice"));
+
+    if (platformExpert) {
+        CFStringRef serialNumberCf = (CFStringRef) IORegistryEntryCreateCFProperty(
+            platformExpert,
+            CFSTR(kIOPlatformSerialNumberKey),
+            kCFAllocatorDefault,
+            0);
+
+        if (serialNumberCf) {
+            char serial_str[128];
+            if (CFStringGetCString(serialNumberCf, serial_str, sizeof(serial_str), kCFStringEncodingUTF8)) {
+                // Hardware serial numbers are considered reliable and stable
+                if (strlen(serial_str) > 0) {
+                    // Generate a UUID from the serial number
+                    char uuid_input[150];
+                    snprintfz(uuid_input, sizeof(uuid_input), "mac-serial:%s", serial_str);
+                    machine_id = UUID_generate_from_hash(uuid_input, strlen(uuid_input));
+
+                    CFRelease(serialNumberCf);
+                    IOObjectRelease(platformExpert);
+                    return machine_id;
+                }
+            }
+            CFRelease(serialNumberCf);
+        }
+        IOObjectRelease(platformExpert);
+    }
+
+    // If no reliable machine ID could be found, return NO_MACHINE_ID
+    return NO_MACHINE_ID;
+}
+
+#elif defined(OS_WINDOWS)
+#include <windows.h>
+
+static ND_UUID get_machine_id(void) {
+    ND_UUID machine_id = { 0 };
+    HKEY hKey;
+
+    // Try to get MachineGuid from registry - this is the most reliable machine ID on Windows
+    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
+        WCHAR guidW[64];
+        DWORD guidSize = sizeof(guidW);
+        DWORD type = REG_SZ;
+
+        if (RegQueryValueExW(hKey, L"MachineGuid", NULL, &type, (LPBYTE)guidW, &guidSize) == ERROR_SUCCESS) {
+            char guid_str[UUID_STR_LEN];
+
+            // Convert GUID to UTF-8
+            if (WideCharToMultiByte(CP_UTF8, 0, guidW, -1, guid_str, sizeof(guid_str), NULL, NULL) > 0) {
+                if (uuid_parse(guid_str, machine_id.uuid) == 0) {
+                    RegCloseKey(hKey);
+                    return machine_id;
+                }
+            }
+        }
+        RegCloseKey(hKey);
+    }
+
+    // If no reliable machine ID could be found, return NO_MACHINE_ID
+    return NO_MACHINE_ID;
+}
+
+#endif // OS_WINDOWS
+
+ND_UUID os_machine_id(void) {
+    // Fast path - return cached value if available
+    if(!UUIDiszero(cached_machine_id))
+        return cached_machine_id;
+
+    spinlock_lock(&spinlock);
+
+    // Check again under lock in case another thread set it
+    if(UUIDiszero(cached_machine_id)) {
+        cached_machine_id = get_machine_id();
+
+        // Log the result if debugging is enabled
+        if(UUIDeq(cached_machine_id, NO_MACHINE_ID))
+            nd_log(NDLS_DAEMON, NDLP_WARNING, "OS_MACHINE_ID: Could not detect a reliable machine ID");
+        else {
+            char buf[UUID_STR_LEN];
+            uuid_unparse_lower(cached_machine_id.uuid, buf);
+            nd_log(NDLS_DAEMON, NDLP_WARNING, "OS_MACHINE_ID: machine ID found '%s'", buf);
+        }
+    }
+
+    spinlock_unlock(&spinlock);
+    return cached_machine_id;
+}
diff --git a/src/libnetdata/os/machine_id.h b/src/libnetdata/os/machine_id.h
new file mode 100644
index 0000000000..a7f92421ce
--- /dev/null
+++ b/src/libnetdata/os/machine_id.h
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef NETDATA_MACHINE_ID_H
+#define NETDATA_MACHINE_ID_H
+
+#include "libnetdata/libnetdata.h"
+#include "libnetdata/uuid/uuid.h"
+
+/**
+ * Special value returned when a reliable machine ID cannot be determined
+ */
+#define NO_MACHINE_ID (ND_UUID){ .parts = { .hig64 = 1, .low64 = 1 } }
+
+/**
+ * Get the machine ID
+ *
+ * Returns a UUID that uniquely identifies the machine.
+ * On Linux, this is the systemd machine-id.
+ * On other systems, it uses platform-specific values.
+ *
+ * The value is cached after first call.
+ * Returns NO_MACHINE_ID when a reliable machine ID cannot be detected.
+ *
+ * @return ND_UUID The machine ID
+ */
+ND_UUID os_machine_id(void);
+
+#endif // NETDATA_MACHINE_ID_H
diff --git a/src/libnetdata/os/os.h b/src/libnetdata/os/os.h
index 19dbe4caf7..c9b76fc3ae 100644
--- a/src/libnetdata/os/os.h
+++ b/src/libnetdata/os/os.h
@@ -40,6 +40,7 @@
 #include "run_dir.h"
 #include "file_lock.h"
 #include "mmap_limit.h"
+#include "machine_id.h"
 
 // this includes windows.h to the whole of netdata
 // so various conflicts arise