diff --git a/lib/rapi/client.py b/lib/rapi/client.py
index e2d7be51a8f810ce6242fbc301b039078647d6fa..5088172aade436153bd65874c256920286daa3e9 100644
--- a/lib/rapi/client.py
+++ b/lib/rapi/client.py
@@ -60,6 +60,13 @@ NODE_ROLE_REGULAR = "regular"
 # Internal constants
 _REQ_DATA_VERSION_FIELD = "__version__"
 _INST_CREATE_REQV1 = "instance-create-reqv1"
+_INST_NIC_PARAMS = frozenset(["mac", "ip", "mode", "link", "bridge"])
+_INST_CREATE_V0_DISK_PARAMS = frozenset(["size"])
+_INST_CREATE_V0_PARAMS = frozenset([
+  "os", "pnode", "snode", "iallocator", "start", "ip_check", "name_check",
+  "hypervisor", "file_storage_dir", "file_driver", "dry_run",
+  ])
+_INST_CREATE_V0_DPARAMS = frozenset(["beparams", "hvparams"])
 
 
 class Error(Exception):
@@ -676,13 +683,82 @@ class GanetiRapiClient(object):
       body.update((key, value) for key, value in kwargs.iteritems()
                   if key != "dry_run")
     else:
-      # TODO: Implement instance creation request data version 0
-      # When implementing version 0, care should be taken to refuse unknown
-      # parameters and invalid values. The interface of this function must stay
+      # Old request format (version 0)
+
+      # The following code must make sure that an exception is raised when an
+      # unsupported setting is requested by the caller. Otherwise this can lead
+      # to bugs difficult to find. The interface of this function must stay
       # exactly the same for version 0 and 1 (e.g. they aren't allowed to
       # require different data types).
-      raise NotImplementedError("Support for instance creation request data"
-                                " version 0 is not yet implemented")
+
+      # Validate disks
+      for idx, disk in enumerate(disks):
+        unsupported = set(disk.keys()) - _INST_CREATE_V0_DISK_PARAMS
+        if unsupported:
+          raise GanetiApiError("Server supports request version 0 only, but"
+                               " disk %s specifies the unsupported parameters"
+                               " %s, allowed are %s" %
+                               (idx, unsupported,
+                                list(_INST_CREATE_V0_DISK_PARAMS)))
+
+      assert (len(_INST_CREATE_V0_DISK_PARAMS) == 1 and
+              "size" in _INST_CREATE_V0_DISK_PARAMS)
+      disk_sizes = [disk["size"] for disk in disks]
+
+      # Validate NICs
+      if not nics:
+        raise GanetiApiError("Server supports request version 0 only, but"
+                             " no NIC specified")
+      elif len(nics) > 1:
+        raise GanetiApiError("Server supports request version 0 only, but"
+                             " more than one NIC specified")
+
+      assert len(nics) == 1
+
+      unsupported = set(nics[0].keys()) - _INST_NIC_PARAMS
+      if unsupported:
+        raise GanetiApiError("Server supports request version 0 only, but"
+                             " NIC 0 specifies the unsupported parameters %s,"
+                             " allowed are %s" %
+                             (unsupported, list(_INST_NIC_PARAMS)))
+
+      # Validate other parameters
+      unsupported = (set(kwargs.keys()) - _INST_CREATE_V0_PARAMS -
+                     _INST_CREATE_V0_DPARAMS)
+      if unsupported:
+        allowed = _INST_CREATE_V0_PARAMS.union(_INST_CREATE_V0_DPARAMS)
+        raise GanetiApiError("Server supports request version 0 only, but"
+                             " the following unsupported parameters are"
+                             " specified: %s, allowed are %s" %
+                             (unsupported, list(allowed)))
+
+      # All required fields for request data version 0
+      body = {
+        _REQ_DATA_VERSION_FIELD: 0,
+        "name": name,
+        "disk_template": disk_template,
+        "disks": disk_sizes,
+        }
+
+      # NIC fields
+      assert len(nics) == 1
+      assert not (set(body.keys()) & set(nics[0].keys()))
+      body.update(nics[0])
+
+      # Copy supported fields
+      assert not (set(body.keys()) & set(kwargs.keys()))
+      body.update(dict((key, value) for key, value in kwargs.items()
+                       if key in _INST_CREATE_V0_PARAMS))
+
+      # Merge dictionaries
+      for i in (value for key, value in kwargs.items()
+                if key in _INST_CREATE_V0_DPARAMS):
+        assert not (set(body.keys()) & set(i.keys()))
+        body.update(i)
+
+      assert not (set(kwargs.keys()) -
+                  (_INST_CREATE_V0_PARAMS | _INST_CREATE_V0_DPARAMS))
+      assert not (set(body.keys()) & _INST_CREATE_V0_DPARAMS)
 
     return self._SendRequest(HTTP_POST, "/%s/instances" % GANETI_RAPI_VERSION,
                              query, body)
diff --git a/test/ganeti.rapi.client_unittest.py b/test/ganeti.rapi.client_unittest.py
index 54fd5ff23eb5839027d35c5cbc7366ecedc4151c..851ec138f8f03fb76b416c950acfd4a03ea4bd84 100755
--- a/test/ganeti.rapi.client_unittest.py
+++ b/test/ganeti.rapi.client_unittest.py
@@ -26,6 +26,7 @@ import re
 import unittest
 import warnings
 
+from ganeti import constants
 from ganeti import http
 from ganeti import serializer
 
@@ -89,6 +90,9 @@ class RapiMock(object):
   def AddResponse(self, response, code=200):
     self._responses.insert(0, (code, response))
 
+  def CountPending(self):
+    return len(self._responses)
+
   def GetLastHandler(self):
     return self._last_handler
 
@@ -111,6 +115,15 @@ class RapiMock(object):
     return code, response
 
 
+class TestConstants(unittest.TestCase):
+  def test(self):
+    self.assertEqual(client.GANETI_RAPI_PORT, constants.DEFAULT_RAPI_PORT)
+    self.assertEqual(client.GANETI_RAPI_VERSION, constants.RAPI_VERSION)
+    self.assertEqual(client._REQ_DATA_VERSION_FIELD, rlib2._REQ_DATA_VERSION)
+    self.assertEqual(client._INST_CREATE_REQV1, rlib2._INST_CREATE_REQV1)
+    self.assertEqual(client._INST_NIC_PARAMS, constants.INIC_PARAMS)
+
+
 class RapiMockTest(unittest.TestCase):
   def test(self):
     rapi = RapiMock()
@@ -196,6 +209,10 @@ class GanetiRapiClientTests(testutils.GanetiTestCase):
       self.assertEqual(features, self.client.GetFeatures())
       self.assertHandler(rlib2.R_2_features)
 
+  def testGetFeaturesNotFound(self):
+    self.rapi.AddResponse(None, code=404)
+    self.assertEqual([], self.client.GetFeatures())
+
   def testGetOperatingSystems(self):
     self.rapi.AddResponse("[\"beos\"]")
     self.assertEqual(["beos"], self.client.GetOperatingSystems())
@@ -259,10 +276,91 @@ class GanetiRapiClientTests(testutils.GanetiTestCase):
     self.assertQuery("static", ["1"])
 
   def testCreateInstanceOldVersion(self):
-    self.rapi.AddResponse(serializer.DumpJson([]))
-    self.assertRaises(NotImplementedError, self.client.CreateInstance,
-                      "create", "inst1.example.com", "plain", [], [],
-                      dry_run=True)
+    # No NICs
+    self.rapi.AddResponse(None, code=404)
+    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
+                      "create", "inst1.example.com", "plain", [], [])
+    self.assertEqual(self.rapi.CountPending(), 0)
+
+    # More than one NIC
+    self.rapi.AddResponse(None, code=404)
+    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
+                      "create", "inst1.example.com", "plain", [],
+                      [{}, {}, {}])
+    self.assertEqual(self.rapi.CountPending(), 0)
+
+    # Unsupported NIC fields
+    self.rapi.AddResponse(None, code=404)
+    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
+                      "create", "inst1.example.com", "plain", [],
+                      [{"x": True, "y": False}])
+    self.assertEqual(self.rapi.CountPending(), 0)
+
+    # Unsupported disk fields
+    self.rapi.AddResponse(None, code=404)
+    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
+                      "create", "inst1.example.com", "plain",
+                      [{}, {"moo": "foo",}], [{}])
+    self.assertEqual(self.rapi.CountPending(), 0)
+
+    # Unsupported fields
+    self.rapi.AddResponse(None, code=404)
+    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
+                      "create", "inst1.example.com", "plain", [], [{}],
+                      hello_world=123)
+    self.assertEqual(self.rapi.CountPending(), 0)
+
+    self.rapi.AddResponse(None, code=404)
+    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
+                      "create", "inst1.example.com", "plain", [], [{}],
+                      memory=128)
+    self.assertEqual(self.rapi.CountPending(), 0)
+
+    # Normal creation
+    testnics = [
+      [{}],
+      [{ "mac": constants.VALUE_AUTO, }],
+      [{ "ip": "192.0.2.99", "mode": constants.NIC_MODE_ROUTED, }],
+      ]
+
+    testdisks = [
+      [],
+      [{ "size": 128, }],
+      [{ "size": 321, }, { "size": 4096, }],
+      ]
+
+    for idx, nics in enumerate(testnics):
+      for disks in testdisks:
+        beparams = {
+          constants.BE_MEMORY: 512,
+          constants.BE_AUTO_BALANCE: False,
+          }
+        hvparams = {
+          constants.HV_MIGRATION_PORT: 9876,
+          constants.HV_VNC_TLS: True,
+          }
+
+        self.rapi.AddResponse(None, code=404)
+        self.rapi.AddResponse(serializer.DumpJson(3122617 + idx))
+        job_id = self.client.CreateInstance("create", "inst1.example.com",
+                                            "plain", disks, nics,
+                                            pnode="node99", dry_run=True,
+                                            hvparams=hvparams,
+                                            beparams=beparams)
+        self.assertEqual(job_id, 3122617 + idx)
+        self.assertHandler(rlib2.R_2_instances)
+        self.assertDryRun()
+        self.assertEqual(self.rapi.CountPending(), 0)
+
+        data = serializer.LoadJson(self.http.last_request.data)
+        self.assertEqual(data["name"], "inst1.example.com")
+        self.assertEqual(data["disk_template"], "plain")
+        self.assertEqual(data["pnode"], "node99")
+        self.assertEqual(data[constants.BE_MEMORY], 512)
+        self.assertEqual(data[constants.BE_AUTO_BALANCE], False)
+        self.assertEqual(data[constants.HV_MIGRATION_PORT], 9876)
+        self.assertEqual(data[constants.HV_VNC_TLS], True)
+        self.assertEqual(data["disks"], [disk["size"] for disk in disks])
 
   def testCreateInstance(self):
     self.rapi.AddResponse(serializer.DumpJson([rlib2._INST_CREATE_REQV1]))