diff --git a/lib/serializer.py b/lib/serializer.py
index cbc11fa658ab60b277a724e29511077c53c36ed6..f0081551e0db55be4d4a2191383c38fc9dc4ae7c 100644
--- a/lib/serializer.py
+++ b/lib/serializer.py
@@ -140,6 +140,28 @@ def LoadSignedJson(txt, key):
   return LoadJson(msg), salt
 
 
+def LoadAndVerifyJson(raw, verify_fn):
+  """Parses and verifies JSON data.
+
+  @type raw: string
+  @param raw: Input data in JSON format
+  @type verify_fn: callable
+  @param verify_fn: Verification function, usually from L{ht}
+  @return: De-serialized data
+
+  """
+  try:
+    data = LoadJson(raw)
+  except Exception, err:
+    raise errors.ParseError("Can't parse input data: %s" % err)
+
+  if not verify_fn(data):
+    raise errors.ParseError("Data does not match expected format: %s" %
+                            verify_fn)
+
+  return data
+
+
 Dump = DumpJson
 Load = LoadJson
 DumpSigned = DumpSignedJson
diff --git a/lib/tools/prepare_node_join.py b/lib/tools/prepare_node_join.py
index deedd0b3207228415e5b01ea2058fc224c503f28..b88e02e7e8cafc83516caef2ba8b1521b95066eb 100644
--- a/lib/tools/prepare_node_join.py
+++ b/lib/tools/prepare_node_join.py
@@ -281,16 +281,7 @@ def LoadData(raw):
   @rtype: dict
 
   """
-  try:
-    data = serializer.LoadJson(raw)
-  except Exception, err:
-    raise errors.ParseError("Can't parse input data: %s" % err)
-
-  if not _DATA_CHECK(data):
-    raise errors.ParseError("Input data does not match expected format: %s" %
-                            _DATA_CHECK)
-
-  return data
+  return serializer.LoadAndVerifyJson(raw, _DATA_CHECK)
 
 
 def Main():
diff --git a/test/ganeti.serializer_unittest.py b/test/ganeti.serializer_unittest.py
index 75c498c06d0fa9a35d0d77322b3cbe9820dc66bf..45a3932386e27c3fda44dea7166b3998e016900a 100755
--- a/test/ganeti.serializer_unittest.py
+++ b/test/ganeti.serializer_unittest.py
@@ -26,6 +26,7 @@ import unittest
 
 from ganeti import serializer
 from ganeti import errors
+from ganeti import ht
 
 import testutils
 
@@ -106,5 +107,29 @@ class TestSerializer(testutils.GanetiTestCase):
                       serializer.DumpJson(tdata), "mykey")
 
 
+class TestLoadAndVerifyJson(unittest.TestCase):
+  def testNoJson(self):
+    self.assertRaises(errors.ParseError, serializer.LoadAndVerifyJson,
+                      "", NotImplemented)
+    self.assertRaises(errors.ParseError, serializer.LoadAndVerifyJson,
+                      "}", NotImplemented)
+
+  def testVerificationFails(self):
+    self.assertRaises(errors.ParseError, serializer.LoadAndVerifyJson,
+                      "{}", lambda _: False)
+
+    verify_fn = ht.TListOf(ht.TNonEmptyString)
+    try:
+      serializer.LoadAndVerifyJson("{}", verify_fn)
+    except errors.ParseError, err:
+      self.assertTrue(str(err).endswith(str(verify_fn)))
+    else:
+      self.fail("Exception not raised")
+
+  def testSuccess(self):
+    self.assertEqual(serializer.LoadAndVerifyJson("{}", ht.TAny), {})
+    self.assertEqual(serializer.LoadAndVerifyJson("\"Foo\"", ht.TAny), "Foo")
+
+
 if __name__ == "__main__":
   testutils.GanetiTestProgram()