diff --git a/src/knot/server/zone-load.c b/src/knot/server/zone-load.c
index 9b1a29bf53de42221e00a814e3e8e0002ab05a51..524b07e0a25b90722b1e5c4789dfe5a08a36436c 100644
--- a/src/knot/server/zone-load.c
+++ b/src/knot/server/zone-load.c
@@ -118,12 +118,25 @@ zone_t *load_zone_file(conf_zone_t *conf)
 		return NULL;
 	}
 
+	/* Create the new zone. */
+	zone_t *zone = zone_new((conf_zone_t *)conf);
+	if (zone == NULL) {
+		log_zone_error("Failed to create zone '%s': %s\n",
+		               conf->name, knot_strerror(KNOT_ENOMEM));
+		return NULL;
+	}
+
 	struct stat st;
 	if (stat(conf->file, &st) < 0) {
 		/* Go silently and reset mtime to 0. */
 		memset(&st, 0, sizeof(struct stat));
 	}
 
+	/* Set the zone type (master/slave). If zone has no master set, we
+	 * are the primary master for this zone (i.e. zone type = master).
+	 */
+	zl.creator->master = (zone_master(zone) == NULL);
+
 	/* Load the zone contents. */
 	knot_zone_contents_t *zone_contents = zonefile_load(&zl);
 	zonefile_close(&zl);
@@ -134,15 +147,6 @@ zone_t *load_zone_file(conf_zone_t *conf)
 		return NULL;
 	}
 
-	/* Create the new zone. */
-	zone_t *zone = zone_new((conf_zone_t *)conf);
-	if (zone == NULL) {
-		log_zone_error("Failed to create zone '%s': %s\n",
-		               conf->name, knot_strerror(KNOT_ENOMEM));
-		knot_zone_contents_deep_free(&zone_contents);
-		return NULL;
-	}
-
 	/* Link zone contents to zone. */
 	zone->contents = zone_contents;
 
diff --git a/src/knot/updates/xfr-in.c b/src/knot/updates/xfr-in.c
index c94f2719e72cb07f10e45983e504ef5aa6db9784..d47468ba08236926894ef1f446332815fa2ca6dd 100644
--- a/src/knot/updates/xfr-in.c
+++ b/src/knot/updates/xfr-in.c
@@ -312,8 +312,8 @@ int xfrin_process_axfr_packet(knot_ns_xfr_t *xfr, knot_zone_contents_t **zone)
 	}
 
 	// Init zone creator
-	zcreator_t zc = {.z = *zone,
-	                 .last_node = NULL, .ret = KNOT_EOK };
+	zcreator_t zc = {.z = *zone, .last_node = NULL,
+	                 .master = false, .ret = KNOT_EOK };
 
 
 	while (ret == KNOT_EOK && rr) {
diff --git a/src/knot/zone/semantic-check.c b/src/knot/zone/semantic-check.c
index a72ca9b5a7a4394a3e89432656ceb3e2dc9ecab4..cb3a5c64db77365c586f04bc8b37ea3ff7b3995c 100644
--- a/src/knot/zone/semantic-check.c
+++ b/src/knot/zone/semantic-check.c
@@ -277,16 +277,12 @@ static bool rrset_ttls_equal(const knot_rrset_t *rrset)
  * \param rr RRSet we're adding into.
  * \param zname Zone name for logging.
  */
-static void rrset_ttl_check(err_handler_t *handler,
-                            const knot_rrset_t *rr, const knot_node_t *n)
+static int rrset_ttl_check(const knot_rrset_t *rr)
 {
 	if (rr->type != KNOT_RRTYPE_RRSIG && !rrset_ttls_equal(rr)) {
-		/* Prepare additional info string. */
-		char info_str[64] = { '\0' };
-		char type_str[16] = { '\0' };
-		knot_rrtype_to_string(rr->type, type_str, sizeof(type_str));
-		snprintf(info_str, sizeof(info_str), "Record type: %s.", type_str);
-		err_handler_handle_error(handler, n, ZC_ERR_TTL_MISMATCH, info_str);
+		return KNOT_EMALF;
+	} else {
+		return KNOT_EOK;
 	}
 }
 
@@ -946,15 +942,35 @@ int sem_check_node_plain(const knot_zone_contents_t *zone,
 	}
 }
 
-int sem_check_rrset(const knot_node_t *node,
-                    const knot_rrset_t *rrset,
-                    err_handler_t *handler)
+int sem_check_rrset(const knot_node_t *node, const knot_rrset_t *rrset,
+                    bool master, err_handler_t *handler)
 {
 	if (node == NULL || rrset == NULL || handler == NULL) {
 		return KNOT_EINVAL;
 	}
 
-	rrset_ttl_check(handler, rrset, node);
+	int ret = rrset_ttl_check(rrset);
+
+	/* Do the check both on master and slave because of the warning,
+	 * but fail only on master. */
+	if (ret != KNOT_EOK) {
+		/* Prepare additional info string. */
+		char info_str[64] = { '\0' };
+		char type_str[16] = { '\0' };
+		knot_rrtype_to_string(rr->type, type_str, sizeof(type_str));
+		snprintf(info_str, sizeof(info_str), "Record type: %s.", type_str);
+
+		if (master) {
+			/*! \todo REPLACE WITH FATAL ERROR */
+			err_handler_handle_error(handler, n, ZC_ERR_TTL_MISMATCH,
+			                         info_str);
+			return KNOT_EMALF;
+		} else {
+			err_handler_handle_error(handler, n, ZC_ERR_TTL_MISMATCH,
+			                         info_str);
+		}
+	}
+
 	return KNOT_EOK;
 }
 
diff --git a/src/knot/zone/semantic-check.h b/src/knot/zone/semantic-check.h
index 649db7600a3d0d574bc634e5c8565e154287d088..7eeeabda859b15167d59d6294764a1fdbcc22cb7 100644
--- a/src/knot/zone/semantic-check.h
+++ b/src/knot/zone/semantic-check.h
@@ -229,13 +229,17 @@ int sem_check_node_plain(const knot_zone_contents_t *zone,
  *
  * \param node     Node containg the RRSet.
  * \param rrset    RRSet to be tested.
+ * \param master   Set to true if server is primary master for this zone.
  * \param handler  Error handler.
  *
+ * If \a master is true, additional check is performed which results in error
+ * of the RR has different TTL than the rest of the RRSet.
+ *
  * \return KNOT_E*
  */
 int sem_check_rrset(const knot_node_t *node,
                     const knot_rrset_t *rrset,
-                    err_handler_t *handler);
+                    bool master, err_handler_t *handler);
 
 #endif // _KNOT_SEMANTIC_CHECK_H_
 
diff --git a/src/knot/zone/zone-create.c b/src/knot/zone/zone-create.c
index b83ffd59d87ad65befb011718e140acac28eb8a6..b654c243241a366843a31b1d31735bac446f6e2b 100644
--- a/src/knot/zone/zone-create.c
+++ b/src/knot/zone/zone-create.c
@@ -119,7 +119,8 @@ int zcreator_step(zcreator_t *zc, knot_rrset_t *rr)
 	bool sem_fatal_error = false;
 	err_handler_t err_handler;
 	err_handler_init(&err_handler);
-	ret = sem_check_rrset(n, zone_rrset, &err_handler);
+
+	ret = sem_check_rrset(n, zone_rrset, zc->master, &err_handler);
 	if (ret != KNOT_EOK) {
 		return ret;
 	}
diff --git a/src/knot/zone/zone-create.h b/src/knot/zone/zone-create.h
index 65d6436586166fe78380ed26628a3ba6d0591399..a8aed1150894d88a6e9f720e91e733ff9ac9f8f9 100644
--- a/src/knot/zone/zone-create.h
+++ b/src/knot/zone/zone-create.h
@@ -38,6 +38,8 @@
 typedef struct zcreator {
 	knot_zone_contents_t *z;  /*!< Created zone. */
 	knot_node_t *last_node;   /*!< Last used node, use to save zone lookup. */
+	bool master;              /*!< Master flag. True if server is a primary
+	                               master for the zone. */
 	int ret;                  /*!< Return value. */
 } zcreator_t;